Entwickler-Ecke
Algorithmen, Optimierung und Assembler - Algorithmus für Silbentrennung
MisterAHA - So 04.01.09 13:11
Titel: Algorithmus für Silbentrennung
hallo leute,
ich beschäftigte mich seit einiger zeit mit der silbentrennung. dazu habe nun schon seit fast einer woche das web auf den kopf gestellt, bin aber leider zu keinem brauchbarem ergebnis gekommen. :roll:
das problem das es zu bewältigen geht, ist recht einfacher natur: um einen zeilenumbruch in datenbanken zu realisieren (rein optisch) muss eine silbentrennung her.
es muss ja nicht unbedingt 100%ig genau sein, aber so um die 90-95%.
hat einer von euch eine idee oder gar einen algorithmus parat?
vielen vielen danke im voraus für eure bemühungen.
mfg andreas
AXMD - So 04.01.09 13:16
Schau dir doch mal die Algorithmen an, die LaTeX verwendet - die basieren meines Wissens nach auf sprachabhängigen Wahrscheinlichkeiten zur Silbentrennung. Das funktioniert relativ gut :)
AXMD
MisterAHA - So 04.01.09 13:22
danke erstmal für deine schnelle antwort,
den algorithmus habe ich leider nicht gefunden, sondern eher nur eine *.exe die fast 600MB gross ist. :?
alzaimar - So 04.01.09 13:49
Ich hab vor 25 Jahren oder so mal einen Silbentrenner geschrieben, der für seine Größe (und mein Alter) recht brauchbar war. Er basiert auf Vorsilben, 'aussprechbaren' Silben und Teilwörtern. Daneben habe ich noch ein Wörterbuch für Ausnahmen implementiert. Das Resultat war aber für damalige Verhältnisse recht ordendlich.
Eine Beschreibung des TeX (nicht LaTeX)-Algorithmus ist hier zu finden
http://en.wikipedia.org/wiki/Hyphenation_algorithm Dort sind auch Links zu Implementierungen in Java, Ruby, Perl etc. Delphi ist -wie üblich- nicht dabei.
MisterAHA - So 04.01.09 13:53
das ist wohl immer unser delphi-nutzer-problem alzaimar,
hast du denn den quelltext denn noch da? vielleicht könnte man ihn ja nutzen?
mfg andreas
MisterAHA - So 04.01.09 14:19
ich habe einen sehr alten quelltext im netz gefunden.
was haltet ihr denn davon?
Die Funktion wird mit
silbentrennung("trennungswort")
aufgerufen und liefert eine Liste aus Positionswerten an denen getrennt werden darf.
Die variable "verbindungen" wird verwendet, um typische Zusammenhängende Laute zu definieren. Dabei wird in kauf genommen, das es viele Ausnahmen gibt, bei denen ein entsprechendes Wort anders getrennt wird.
Zeilen mit "--" sind Kommentare, die Nummerierung in OpenScript beginnt mit 1 anstatt mit 0.
Here we go
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38:
| to get silbentrennung string welchesWort local int zeichenAnzahl, i local logical trennenErlaubt local string z, z0, z1, v local stack trennPositionen zeichenAnzahl = charCount(welchesWort) if zeichenAnzahl > 2 trennenErlaubt = false vokale = "a,e,i,o,u,ä,ü,ö" -- "sch" wie in "A_sche" -- "ch" wie in "Untersu_chen" -- "ph" wie in "Ste_phan" -- "ck" wie in "Zu_cker" -- "pf" wie "A_pfel" -- "br" wie in "Unter_brechung" -- "pl" wie "Finanz_plan" -- "tr" wie in "An_trag" -- "st" wie in "Auf_stehen" -- "gr" wie in "Hinter_grund" verbindungen = "sch,ch,ph,ck,pf,br,pl,tr,st,gr" trennungen = "-,/,\,*,#,;,.,+,=,),(,&,!,?,<,>,:, ,_,~" step i from 2 to (zeichenAnzahl-1) z0 = char i-1 of welchesWort if trennenErlaubt = false and istIn(z0,vokale) trennenErlaubt = true end if if trennenErlaubt z = char i of welchesWort z1 = char i+1 of welchesWort v = z0 & z if v = "ch" and i > 2 and char i-2 of welchesWort = "s" v = "sch" end if if istIn(z1,vokale) and istIn(z,vokale) = false and istIn(z,trennungen) = false and istIn(z0,trennungen) = false if istIn(v,verbindungen) push (i-charCount(v)+1) onto trennPositionen else push i onto trennPositionen end if end if end if end step end if return trennPositionen end silbentrennung |
den code habe ch genauso im netz, ohne einrückung gefunden. also bissl schwieriger zu lesen, aber immerhin
BenBE - So 04.01.09 14:28
Bitte korrekte Quellnangabe nachliefern! "Im Netz" ist dies nämlich nicht ;-)
Delete - So 04.01.09 14:32
BenBE hat folgendes geschrieben : |
Bitte korrekte Quellnangabe nachliefern! "Im Netz" ist dies nämlich nicht ;-) |
Woher willst du das wissen? Ich glaube er meinte kein Spinnennetz!
MisterAHA - So 04.01.09 15:43
gäbe es denn nun einen verbesserungsvorschlag zu entsprechendem code? ^^
jaenicke - So 04.01.09 15:51
Hast du ihn denn ausprobiert? Sind die Ergebnisse für dich nicht ausreichend? Oder wie meinst du das?
MisterAHA - So 04.01.09 15:57
ich glaube schon, dass es soweit passt.
aber vielleicht hat einer von euch noch eine gute idee dazu, wo der code um die ohren fliegen könnte, verstehtst du?
dann könnte man eine solche behandlung des problems im vorfeld zu einem "non-problem" machen!
mfg andreas
BenBE - So 04.01.09 15:59
Erstmal übersetzen würd ich vorschlagen ;-)
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46:
| function silbentrennung(welchesWort: String): TStack; var zeichenAnzahl, i: Integer; trennenErlaubt: Boolean; z, z0, z1, v: String; trennPositionen: TStack; begin zeichenAnzahl := Length(welchesWort); if zeichenAnzahl > 2 Then Begin trennenErlaubt := false; vokale := 'a,e,i,o,u,ä,ü,ö'; verbindungen := 'sch,ch,ph,ck,pf,br,pl,tr,st,gr'; trennungen := '-,/,\,*,#,;,.,+,=,),(,&,!,?,<,>,:, ,_,~'; for i := 2 to (zeichenAnzahl-1) do Begin z0 := welchesWort[i-1]; if not trennenErlaubt and istIn(z0,vokale) Then Begin trennenErlaubt := true; end; if trennenErlaubt Then Begin z := welchesWort[i]; z1 := welchesWort[i+1]; v := z0 & z; if (v = 'ch') and (i > 2) and (welchesWort[i-2] = 's') Then Begin v := 'sch'; end; if istIn(z1,vokale) and not istIn(z,vokale) and not istIn(z,trennungen) and not istIn(z0,trennungen) then Begin if istIn(v,verbindungen) Then Begin trennPositionen.push(i-charCount(v)+1); end else Begin trennPositionen.push(i); end; end; end; end; end; Result := trennPositionen; end; |
k.A. ob ich das jetzt grad on-the-fly alles korrekt gelesen hab ...
ffprogramming - Do 08.01.09 19:56
Titel: schwer
ich hab mich mal an den TeX Algorythmus herangewagt das fand ich ziemlich schwer den zu impledieren.
Jakob_Ullmann - Do 08.01.09 20:01
Also was meistens einigermaßen Passend erscheint: Zwischen Vokal und Konsonant. Oder zwischen Doppelkonsonanten. Aber beim genauen Arbeiten wirst du wohl um ein Wörterbuch nicht herumkommen, schätze ich mal.
alzaimar - So 11.01.09 16:04
Vorschlag: Eine kleine Heuristik anlegen, die eine Silbe definiert und daneben eine Liste von Silben ('vor','keit','lich') anlegen, die Ausnahmen beinhaltet. Die wird sicherlich ziemlich lang werden. Dann das Wort in Silben unterteilen. Die Trennung von 'ck' usw. beachten.
Ein erster Ansatz sollte relativ schnell zu implementieren sein. Und immer dran denken: Der Algorithmus soll in erster Linie nur mögliche Trennpositionen finden, jedoch nicht alle! Solanger er keinen Müll produziert, ist das schon die halbe Miete.
Letztendlich würde ich mich jedoch an den TeX-Algo rantasten.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!