Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP] Algorym na zamianę wyrazów pobranych z bazy
Forum PHP.pl > Forum > PHP
amii
Sytuacja wygląda tak mam taką tablę z synonimami w bazie:
  1. CREATE TABLE `synonimy` (
  2. `id` int(11) NOT NULL AUTO_INCREMENT,
  3. `wyrazy` varchar(250) NOT NULL DEFAULT '',
  4. PRIMARY KEY (`id`)
  5. ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=3359 ;
  6.  
  7. --
  8. -- Zrzut danych tabeli `synonimy`
  9. --
  10.  
  11. INSERT INTO `synonimy` (`id`, `wyrazy`) VALUES (1, 'praktycznie=w praktyce\n'),
  12. (2, 'istnienia=egzystencji=obecno&#347ci\n'),
  13. (3, 'konkurencja=rywalizacja\n'),
  14. (4, 'filarów=podstaw=fundamentów\n')


I taką funkcję mającą zamieniać synonimy, której dostarczam parametr:
  1. $text = 'praktycznie istnienia fundamentów konkurencja gwarantuje zasadniczy. Niebyt w tym gdzieś wale korbowym ulokuj jedyna w swoim rodzaju gratki..';

  1. function losuj_synonim($text) {
  2.  
  3. /*********ŁĄCZENIE I POBRANIE SYNONIMÓW Z BAZY***********/
  4. connect_to_db();
  5. $sql = "SELECT wyrazy FROM synonimy";
  6. $zapytaj = mysql_query($sql) or die('Blad w zapytaniu o tresci : ' . mysql_error());
  7. /*********ŁĄCZENIE I POBRANIE SYNONIMÓW Z BAZY***********/
  8.  
  9.  
  10. while($row = mysql_fetch_array($zapytaj)) {
  11.  
  12. $pojedynczy = explode('=', $row['wyrazy']); //rozbijamy tabelę z synonimami
  13. $indeks = mt_rand(0, count($pojedynczy)-1); //losujemy indeks dla synonimu
  14. $a = true; //zmienna kontrolna
  15.  
  16.  
  17.  
  18. foreach ($pojedynczy as $key => $value) {
  19.  
  20. if (strpos($text, $value) && $a) { //jeśli znajdziemy którykolwiek z synonimów w tekście......
  21.  
  22. echo 'To będzie zastąpione: <font color="red"> ' .$value. '</font> tym: <font color="red">' . $pojedynczy[$indeks] . '</font> w tekście o treści: ' . $text . '<br><br>';
  23.  
  24. $text = str_replace($value, $pojedynczy[$indeks], $text); //nadpisujemy tekst z podmienionym synonimem
  25.  
  26. if($value == $pojedynczy[$indeks]) continue;
  27. else $a=false; //w innym przypadku ustawiamy zmienna kontrolna a na false żeby przerwać pętle oznaczyć udana zamianę i nie zamieniać cały czas tego samego wyrazu na rożne synonimy
  28.  
  29. }
  30.  
  31. else break; //jesli a==FALSE lub nie znaleźliśmy synonimu w tekście to wychodzimy z pętli foreach i w pętli while szukamy kolejnego wyrazu
  32.  
  33. }
  34.  
  35. }
  36.  
  37. return $text; //zwracamy podmieniony tekst i przekazujemy zmienna do innej funkcji np. dodającej podmienione artykuły do blogów
  38. }


Funkcja podmienia tylko:
istnienia -> egzystencji
konkurencja ->rywalizacja
istnienia->istnienia
konkurencja->konkurencja

Co zrobić aby to działało na zasadzie, że dla któregokolwiek z tych przykładowych wyrazów w bazie, który zostanie odnaleziony w zmiennej $text czyli:
filarów=podstaw=fundamentów
zostania dokonana podmiana na synonim
filarów=podstaw=fundamentów
tak jednak żeby nie została dokonana zamiana tego samego wyrazu na to samo ?
outsider
Zmodyfikuj warunek, 20 linijka w Twoim listingu:
  1. if (strpos($text, $value) && $a && substr($text, strpos($text, $value), strlen($pojedynczy[$indeks])) != $pojedynczy[$indeks] )
#luq
W ogóle taka struktura bazy danych jest nie do przyjęcia.
Powinno być:

word
wordId | value

word_synonim
synonimId | word1Id | word2Id

a jak już tak bardzo chcesz sobie to ułatwić to zapisuj w bazie zserializowaną tablicę z słowami.

Jak dla mnie ta funkcja powinna przyjmować jako parametr tablicę słów a nie stringa. Nie powinna się łączyć z bazą oraz echować niczego. Funkcja ma przyjmować jakieś wejście mielić to i wyrzucać na wyjście, tylko tyle i nic więcej.
amii
#luq zamieniłem strukturę danych to trochę inaczej niż w Twoim przykładzie i nie działa do końca OK (chociaż skrypt działa szybko dlatego zależy mi na tej strukturze).

Obydwie tabele mają taką samą liczbę rekordów 3700 wyraz przyjmuje taką samą wartość liczbową dla synonimcznych grup. Poniżej dwie grupy synonimów. Przykład:
synonimy
id | wyrazy varchar(100)
1 wazny
2 istotny
3 najwazniejszy
4 slaby
5 mizerny
slowo
id | wyraz int(11)
1 1
2 1
3 1
4 3
5 3

Skrypt źle zamienia wyrazy:
  1. //funkcja losujaca synonimy na podstawie listy zdefiniowanej w bazie danych
  2.  
  3. function losuj_synonim($text) {
  4.  
  5. connect_to_db();
  6.  
  7.  
  8. $pobierz = "SELECT id FROM synonimy as liczba";
  9.  
  10. $zap = mysql_query($pobierz) or die('Blad w zapytaniu SELECT id FROM synonimy as liczba: '. mysql_error());
  11. $liczba_rekordow = mysql_num_rows($zap); //pobieramy liczbe rekordow
  12. $zmienna=1;
  13.  
  14. while($zmienna < $liczba_rekordow) {
  15.  
  16. $sql = "SELECT a.id AS identyfikator, a.wyrazy, b.id AS iden, b.wyraz FROM synonimy a LEFT JOIN slowo b ON b.id=a.id WHERE b.wyraz='$zmienna'"; //pobieramy grupę dopasowanych synonimów z bazy
  17.  
  18. $zapytaj = mysql_query($sql) or die('Blad w zapytaniu o tresci skomplikowane : ' . mysql_error());
  19.  
  20.  
  21. $b=0;
  22. $tabliczka = array(); //!!tworzymy nowa tablice za kazdym razem!!
  23. while($row = mysql_fetch_array($zapytaj)) {
  24. $tabliczka[$b] = $row['wyrazy']; //wpisz wyrazy(synonimy) do tablicy
  25.  
  26. $b++;
  27.  
  28. $ostatni = $row['iden']; //ostatni identyfikator ze slowo zapisujemy wykorzystujemy go w petli zewnetrznej
  29. }
  30.  
  31.  
  32.  
  33. $a=true; //zmienna kontrolna
  34. $indeks = mt_rand(0, count($tabliczka)-1); //losujemy indeks dla synonimu
  35. for($g=0; $g<count($tabliczka); $g++) {
  36. while($indeks==$g) $indeks = mt_rand(0, count($tabliczka)-1); //losujemy indeks dla synonimu
  37. if(strpos($text, $tabliczka[$g]) && $a) {
  38. $text = str_replace($tabliczka[$g], $tabliczka[$indeks], $text);
  39. unset($tabliczka); //!!usuwamy tablice!!
  40. }
  41.  
  42. else {
  43. $a=false; //jedna zamiana wystarczy nie zapetlamy sie dla tego samego wyrazy
  44. break;
  45. }
  46. }
  47. $zmienna = $ostatni; //do pętli zewnetrznej licznik po grupach synonimów jak spojrzycie na przykład z bazy to chyba tak to powinno wyglądać bo odnosimy sie do wyraz z tabeli slowo jak widac grupuje on grupy synonimów
  48.  
  49. }
  50. return $text; //zwracamy podmieniony tekst i przekazujemy zmienna do innej funkcji np. dodajacej podmienione artykuly do blogow
  51. }


Trochę pokręcony ten skrypt ale mam nadzieję, że ktoś będzie w stanie pomóc. Starałem się wszystko wyjaśnić najlepiej w komentarzach.

EDIT:
Dobra załatwione opatrzyłem wykrzyknikami i boldem co trzeba było zmienić.
Jest jeszcze jeden dość problem funkcja nie zamienia słowa 'praktycznie', gwarantuje, zasadniczy mimo, że są w bazie synonimów i tekście
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.