Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Robot do dzielenia wyrazów
Forum PHP.pl > Inne > Hydepark
wcbarbi
Witam, mam taki problem chciałbym stworzyć robot który dzieliłby mi wyrazy według kryterium fonetycznemu pn. za?de?cy?do?wać, u?pro?wa?dzić, na?ra?da, ku?zy?no?wie ponadto każdą oddzielną sylabę wpisywałby do następnej kolumny w wierszu tabeli np. kol./1/Lp. kol./2/zadecydować kol./3/za kol./4/de/ kol./5/cy/ kol./6/do kol./7/wać. Na dzień dzisiejszy mam stworzoną kolumnę tylko z wyrazami czyli kol./1/Lp. kol./2/zadecydować. Czy koś ma ktoś jakiś pomysł?
thek
Szczerze? Prościej napisać syntezator mowy niż robota do podziału sylabicznego smile.gif Wiem bo próbowałem oba. Robota nie zrobiłem, ale syntezator tak. Za dużo w przypadku pierwszego masz reguł do sprawdzenia. A syntezator może Ci się w zasadzie tylko walnąć w słowach typu "erzac" gdyż potraktuje "rz" nie jako osobne litery, ale jako jeden fonem, identyczny z "ż". By je odróżnić, musiałby mieć bazę wyjątków winksmiley.jpg W polskim i tak nie ma najgorzej, bo nie licząc zbitek kończących się na -ka lub mających -ie- oraz kilku innych, podział następuje zazwyczaj po samogłoskach, ale tutaj trzeba jeszcze trochę reguł pododawać, bo "zazwyczaj" to nawet nie większość przypadków. Niestety trzeba mocno się w gramatykę języka wgryźć by tego typu programy pisać. Lepiej więc o zasady dzielenia wyrazów zapytać kogoś kto się naprawdę na tym zna, czyli bez rad polonisty nie ma co tego na poważnie ruszać. Poszperaj ewentualnie za zasadami dzielenia wyrazów na sylaby by jakieś pierwsze, podstawowe próbować zaprogramować. Jeśli z nimi sobie nie poradzisz to nie wiem czy jest sens w to dalej brnąć.
erix
A nie lepiej skorzystać z gotowych słowników sprawdzania pisowni...? Chyba są w nich takie mechanizmy. :]
230005
Thek, a w czym pisałeś ten syntezator? Tak z ciekawości pytam bo się wziąłem ostro za Javę (ale dopiero przedwczoraj tongue.gif) i wpadło mi coś takiego do głowy. Da radę zrobić to niej (znaczy dać pewnie się da, kwestia tylko poziomu trudności - bo może akurat to łatwiej byłoby stworzyć powiedzmy w cpp)?
SHiP
Pisałem coś podobnego kilka dni temu ale zaprzestałem winksmiley.jpg. Być może mój algorytm Ci się przyda(nie jest idealny bo to wersja pre-pre-alpha) ale jeśli go zoptymalizujesz to może ładnie działać.
  1. class SoftHyphenGenerator{
  2.  
  3. public $htmlOn = false;
  4. private $samogloski = Array('a', 'ą', 'e', 'ę', 'i', 'o', 'u', 'y');
  5.  
  6. public static function mbStringToArray ($string) {
  7. $strlen = mb_strlen($string);
  8. while ($strlen) {
  9. $array[] = mb_substr($string,0,1,"UTF-8");
  10. $string = mb_substr($string,1,$strlen,"UTF-8");
  11. $strlen = mb_strlen($string);
  12. }
  13. return $array;
  14. }
  15.  
  16. private function zawieraSamogloske($string, $length, $last)
  17. {
  18. $startLength = $length;
  19. for($length--; $length>=0; $length--)
  20. {
  21. if($string[$length]=='>')
  22. $this -> htmlOn = true;
  23. elseif($string[$length]=='<')
  24. $this -> htmlOn = false;
  25. elseif($this -> htmlOn==false)
  26. {
  27. if($string[$length]=='y' || $string[$length]=='a')
  28. {
  29. if($startLength-$length==1 && in_array($last,$this -> samogloski))
  30. {
  31. return 1;
  32. }
  33. // nie jestem pewien co do tej zasady ale
  34. // nie przenosimy do nastepnej lini "ń" występującego tuż po "y"
  35. // np. młyń-skie ko-ło
  36. if($string[$length+1]=='ń')
  37. {
  38. $length++;
  39. }
  40.  
  41. return -($startLength-$length)+1;
  42.  
  43. }
  44. elseif(in_array($string[$length], $this -> samogloski))
  45. return 1;
  46. }
  47. }
  48. return 0;
  49. }
  50.  
  51.  
  52. public function addSoftHyphen($text)
  53. {
  54. $wordCounter = 0;
  55. $pieces = array_reverse(explode(' ', $text));
  56.  
  57. $returnText = Array();
  58. $this -> htmlOn = false;
  59. foreach($pieces as $piece)
  60. {
  61. $l = mb_strlen($piece,'utf-8');
  62. // pomijamy wyrazy mające mniej niz 4 litery oraz nazwy własne
  63. if($wordCounter==0 || mb_strtolower($piece,"utf-8") == $piece)
  64. {
  65. $newWord = '';
  66. // zamiana stringa na tablicę
  67. $piece = self::mbStringToArray($piece);
  68.  
  69. $samogloska = false;
  70. // sprawdzanie kolejnych znaków wyrazu - od konca
  71. for($l--; $l>=0; $l--)
  72. {
  73. if($piece[$l] == '>') $this -> htmlOn = true;
  74. elseif($piece[$l] == '<') $this -> htmlOn = false;
  75.  
  76. $newWord = $piece[$l].$newWord;
  77.  
  78. if($this -> htmlOn == false)
  79. {
  80. // jest to samogloska
  81. if(in_array(mb_strtolower($piece[$l], 'utf-8'), $this -> samogloski))
  82. {
  83. $samogloska = true;
  84. }
  85. else
  86. {
  87. if($samogloska && $l>1 && ($n = $this -> zawieraSamogloske($piece, $l, $last))!=0)
  88. {
  89. $spolgloska = true;
  90. // literki wczesniej zawierają samogloske "y"
  91. if($n<0)
  92. {
  93. while($n<0)
  94. {
  95. $l--;
  96. $newWord=$piece[$l].$newWord;
  97. $last = array_pop($piece);
  98. $n++;
  99. }
  100. $newWord = '-'.$newWord;
  101. $samogloska = false;
  102. }
  103. else
  104. {
  105. // sprawdzanie głosek 2-literowych tak aby ich nie rozdzielać
  106. switch($piece[$l])
  107. {
  108. case 'h':
  109. $stop = ( mb_strtolower($piece[$l-1])=='c');
  110. break;
  111. case 'z':
  112. $stop = ( mb_strtolower($piece[$l-1])=='c' ||
  113. mb_strtolower($piece[$l-1])=='d' ||
  114. mb_strtolower($piece[$l-1])=='r' ||
  115. mb_strtolower($piece[$l-1])=='s');
  116. break;
  117. case 'ź':
  118. $stop = ( mb_strtolower($piece[$l-1])=='d');
  119. break;
  120. case 'ż':
  121. $stop = ( mb_strtolower($piece[$l-1])=='d');
  122. break;
  123. default:
  124. $stop = ( mb_strtolower($piece[$l-1])=='g');
  125. }
  126.  
  127. if(!$stop){
  128. $newWord = '-'.$newWord;
  129. $samogloska = false;
  130. }
  131. }
  132. }
  133. }
  134. }
  135. $last = array_pop($piece);
  136. }
  137. $returnText[] = $newWord;
  138. $wordCounter++;
  139. }
  140. else
  141. $returnText[] = $piece;
  142. }
  143. return implode(' ',array_reverse($returnText));
  144. }
  145. }
  146.  
  147. $text = new SoftHyphenGenerator;
  148. echo $text -> addSoftHyphen('Jakis przykładowy tekst');


Gdybyś chciał coś porządniejszego(ale nie pamiętam jak z licencją), to poszukaj wp-typography.
thek
Cytat(230005 @ 25.09.2009, 12:49:43 ) *
Thek, a w czym pisałeś ten syntezator? Tak z ciekawości pytam bo się wziąłem ostro za Javę (ale dopiero przedwczoraj tongue.gif ) i wpadło mi coś takiego do głowy. Da radę zrobić to niej (znaczy dać pewnie się da, kwestia tylko poziomu trudności - bo może akurat to łatwiej byłoby stworzyć powiedzmy w cpp)?

Javą syntezator? No jasne smile.gif Raczej trudno powiedzieć czego byś nią nie zrobił winksmiley.jpg Ja pisałem syntezator w Matlabie, ale tak naprawdę tylko dlatego, że miałem go z góry narzucony. "Silnik" jest niezależny od języka, bo to tak naprawdę operacje na wprowadzonym przez użytkownika stringu. Jeśli przetworzysz go do formy fonemów to potem już tylko "sklejasz" nagrania dźwięku odpowiadające mu. W języku polskim jest bodajże 25 lub 26 fonemów + przerwa. Nagraj je i po przetworzeniu stringu tylko "odczytuj" fonemy i "sklejaj" plik dźwiękowy winksmiley.jpg Różnica pomiędzy pytaniem a zdaniem oznajmiającym też jest "matematyczna". W trakcie wypowiedzi zmienia się częstotliwość wypowiadanych liter. Ale tu już musiałbyś modyfikować charakterystykę częstotliwościową nagrania w czasie. Zacznij od ustalenia jakie fonemy ma język polski. a potem już zasady języka w stylu:
k-r-z-a-k -> (zamiana na fonemy) -> k-ż-a-k -> (zamiana na fonemy zgodnie z regułami gramatyki) -> k-sz-a-k ("sz" jest jednym z polskich fonemów )
Jak widzisz jest trochę zabawy i czasem musisz zrobić kilka przebiegów by ostatecznie zapisać wyraz. Zazwyczaj jednak 2 przebiegi zrobią wszystko na tip-top. W moim przypadku musiałem sprawdzić czy po "k" nie występuje fonem "ż" bo w wymowie zamieni się on na "sz" smile.gif Musisz sam regułki zamian znaleźć. Mój był bez modulacji i po prostu "czytał jak leci" nie zwracając uwagi na pytajniki i wykrzykniki, ale robił im po prostu dłuższe przerwy podobnie jak dla kropek i przecinków. Rozwiązanie problemu to więc:
1. Znaleźć fonemy języka polskiego - w google masz tylko ich ilość, ale nie znajdziesz jakie to konkretnie, więc musisz sam się wysilić winksmiley.jpg
2. Opracować formę zapisu "wyrazów fonetycznych" - raz masz fonemy jednoznakowe (a, b itp.), a innym razem dwu(sz, cz, dź) -> coś jak ja mam w przypadku "krzak"
3. Baza reguł, na podstawie której ustalisz ostatecznie wyraz smile.gif Lojalnie ostrzegam, że bez bazy "wyjątków" nie przejdziesz takich słów jak "erzac" czy słów obcych, które nie zawsze są zgodne z polską wymową.

Edit: Jeśli plikami dźwiękowymi byś operował w PHP to w nim także syntezator napisałbyś bez problemu. Tylko konieczność sklejania fonemów w wyrazy i zdania, a przez to operacje na plikach dźwiękowych sprawić mogą trudność programiście jakąś większą używającego języka ze słabym wsparciem multimediów. Ale zawsze po zamianie możesz wyświetlic efekt znów jako string, tak jak ja -> k-sz-a-k smile.gif
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.