Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP] Inteligentny algorytm sprawdzający
Forum PHP.pl > Forum > PHP
mefjiu
Witam,
chciałbym stworzyć dość inteligentny algorytm który sprawdzał by czy w bazie danych nie znajduje się treść którą dodaje user bądź treść bardzo podobna.
Najprościej to zilustrować na przykładnie strony z kawałami. Są kawały na stronie gdy jest ich powiedzmy ponad 7 tyś trudno jest dla takiego administratora zapamiętać który kawał już jest a którego nie ma.
Wiec stworzyć takiego pająka który sprawdzał by bazę w poszukiwaniu takiego samego, lub podobnego kawału np napisanego troszkę inaczej.

Osobiście wymyśliłem coś takiego:

Podaje przykładowy kawał na którym zilustruję mój sposób:

Cytat
Jadą 2 blondynki na rowerach. Nagle jedna z nich zsiada z roweru i zaczyna spuszczać powietrze w obu kołach.
Druga zdziwiona pyta:
- A PO CO TY TO ROBISZ?questionmark.gif
- A BO MAM SIODEŁKO ZA WYSOKO!
Na co ta druga zaczyna majstrować przy swoim rowerze i zamieniać miejscami siodełko z kierownicą.
- A TY CO ROBISZ ? - pyta pierwsza.
- ZAWRACAM. NIE BĘDĘ JEŹDZIŁA Z TAKĄ IDIOTKĄexclamation.gif!


wyciągamy z danego kawału ciąg 3 słów np "Nagle jedna z" (Ciąg przypadkowy, aby było bardziej optymalne dla kawałów typu Przychodzi baba do lekarza :-) )
i teraz jeżeli znajduje taki ciąg w bazie danych to bierze wycina kolejny losowy ciąg 3 wyrazów np "BO MAM SIODEŁKO"; i sprawdza w tych pasujących czy coś takiego już jest jeżeli okazuje się że jest kawału nie dodaje. w przeciwnym wypadku dodaje kawał do strony.

Teraz nasuwa się pytanie co będzie jak trafi tak że 2 ciągi będą takie same i niby kawały będą inne to skrypt ich nie przepuści.

Interesuje mnie wasze spojrzenie na problem, jak wy byście rozwiązali tą sytuację.
Z góry dziękuję za wszelkie rady.
Pozdrawiam mefjiu
PawelC
Możesz to zrobić na takiej zasadzie, masz w bazie tabele pytania a w niej kolumne pytanie, odpowiedź i przykładowo będą tam rekordy:
pytanie: co u Ciebie słychać
odpowiedz: a nic ciekawego
I po pobraniu z bazy rekordów sprawdzasz w nich poprzez preg_match czy w pytaniu znajduje się dany ciąg lub jego część jeżeli tak to pobierze z bazy odpowiedź i wyświetli. To tylko mój tok rozumowania i w taki sposób bym to rozwiązał. Fakt faktem jest trochę zabawy z dodawaniem pytań i odpowiedzi ale efekt końcowy może być bardzo ciekawy. Na wykonanie tego jest bardzo dużo możliwości, trzeba tylko pomyśleć co i jak. mam bota napisanego na forum mybb który po dodaniu nowego tematu sprawdza treść porównuje z pytaniem w bazie i jak znajdzie dane ciągi to na niego odpowiada, odpowiedzią która jest w bazie.
mefjiu
Przeczytałem twój post 3 razy i nic kompletnie z niego nie rozumiem blinksmiley.gif
po co te pytania poco te odpowiedzi ?
ShadowD
Skrypt wywoływany jest przy wpisywaniu nowego kawału do bazy danych...

No to tak smile.gif

Dzieli dodawany tekst i zapisuje w zmiennej (dzieli go oriętując się spacjami)...

A wiedz "mama jedzie do taty pobawić się z nim" dzieli na
$a='mama' $b='jedzie' $c='do' $b=taty i tak dalej
Teraz wciąga 1 rekord z bazy i sprawdza czy wraz z zmiennej $a znajduje się w tym rekordzie
jeśli tak to zmienna $wszystkie wyrazy zwiększa się o +1 a zmienna $takiesame zwiększa się o +1
jeśli nie są takie same to $wszystkie wyrazy zwiększa się o +1 a zmienna $takiesame nie zwiększa się...

Potem sprawdza czy np $wszystkie podzielić na 2 jest większe niż $takiesame jeśli tak nie dodaje kawału...

Pozdrawiam ;p

Ps poprawiłem troche ;p
mefjiu
Pomysł kolegi ShadowD dośc ciekawy tylko jak to się ma na optymalność bo niby cały kawał zostaje zmieniony na zmienne w których jest po jednym wyrazie z kawału czyli sprawdzanie czegoś takiego w bazie np z 7 tys kawałami, nie bedzie długie ?

Ten algorytm nie będzie idealny ponieważ:
co jeżeli kawał będzie pisany np

Kawał w wbazie
"Przychodzi Baba do lekaża
(Dalsza treść kawału)"

Kawał dodany przez usera
"Pewnego pięknego dnia,
Przychodzi Baba do lekaża
(Dalsza treść kawału)"

I taki kawał zostanie dodany do bazy bo: ilość znaków jest większa na prawdopodobieństwo.
ShadowD
Po pierwsze masz racje moj sposób nie jest zbyt szybki...
Po drugie prawdopodobieństwo może być większe np ileośwszystkichwyrazów podzielić na trzy czy nawet 4 większe niż wrazypowtazajacesie więc to ne jest problemem...

Moim zdaniem skrypt nie trudno napisać, można zawsze pozaklejać wyrazy np po d $ab="$a"."$b";
czy też po 3 i sprawdzać trójkami jest to bezpieczniejsze4 i znacznie poprawi szybkość bo 2 wyrazy zwiększą ją o prawie 100% a 3 już o 200% oczywiście prawie...
mefjiu
To co napisałeś jest właśnie sposobem który wymyśliłem tylko ty nie potrzebnie rozdzielasz każdy wyraz do zmiennej a potem je łączysz. Z tym prawdopodobieństwem można było by pokombinować.

Czekam na inne może bardziej, może mniej optymalne rozwiązania, ważne aby sprawne iw pełni działające smile.gif
woj_tas
Pokombinuj coś z funkcjami: similar_text oraz levenshtein
smietek
  1. <?php
  2. $first = "mama";
  3. $second = "mamo";
  4.  
  5. similar_text ($first,$second, $p);
  6.  
  7. echo "$p%";
  8. ?>

Wyświetli, w ilu procentach tekst $first jest podobny do tekstu $second.
Przy dodawaniu nowego kawału po prostu daj pętlę: $first daj jako nowy kawał, a $second jako stary kawał z bazy i już.
mefjiu
No dochodzimy powoli do sedna :-)
Juz prawie widzę przed oczyma doskonały algorytm
Panowie woj_tas i smietek Bardzo mi pomogliście

Kod który podałeś jest smietek jest mało rozbudowany znalazłem coś w maualu na temat tego
  1. <?php
  2. function closest_word($input, $words, &$percent = null) {
  3. $shortest = -1;
  4. foreach ($words as $word) {
  5. $lev = levenshtein($input, $word);
  6.  
  7. if ($lev == 0) {
  8. $closest = $word;
  9. $shortest = 0;
  10. break;
  11. }
  12.  
  13. if ($lev <= $shortest || $shortest < 0) {
  14. $closest = $word;
  15. $shortest = $lev;
  16. }
  17. }
  18.  
  19. $percent = 1 - levenshtein($input, $closest) / max(strlen($input), strlen($closest));
  20.  
  21. return $closest;
  22. }
  23.  
  24. $input = 'carrrrrot';
  25. $words = array('apple','pineapple','banana','orange',
  26.  'radish','carrot','pea','bean','potato');
  27.  
  28. $percent = null;
  29. $found = closest_word($input, $words, $percent);
  30.  
  31. printf('Closest word to "%s": %s (%s%% match)', $input, $found, round($percent * 100, 2));
  32. ?>


czy przypadkiem kod który podałem nie jest tym samym co ty podałeś ?
tylko że zajmuje więcej linijek ?
smietek
Ten kod który podałeś szuka w bazie słów (w tablicy) danego słowa. Jeżeli je znajdzie, wyświetla wynik, jeżeli nie, lecz znalazło dość podobny wynik, również go wyświetla. I ten kod nie korzysta z similar_text(), tylko z levenshtein()
Cysiaczek
Przeniosłem na PHP
mefjiu
Ale ogólna zasada działania jest taka sama ?
gdyby zamienić bazę słów baz danych z kawałami ? efekty byłby taki sam ?

Dzięuję Cysiaczek za przeniesienie posta do zaawansowanego grona fachowców. Ale ja osobiście myślę że to powinno być przedszkole.
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.