Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP]Algorytm, funkcja zdania, słowa, zagadka
Forum PHP.pl > Forum > Przedszkole
Malinaa
Witam,
pytanie w jaki sposób wybrać z całego tekstu fragment, w którym występuje najwięcej powtarzających się słów?

Tekst

Cytat
Mądrość w najwęższym znaczeniu to umiejętność podejmowania uzasadnionych decyzji, które w dłuższej perspektywie przynoszą pozytywne rezultaty. W innym ujęciu można powiedzieć, że mądrość to umiejętność praktycznego wykorzystywania posiadanej wiedzy i doświadczenia. W tym sensie można np. mówić o mądrości nauczyciela, który wykorzystując swoją wiedzę pedagogiczną radzi sobie z kształceniem niesfornego ucznia, czy mądrości szefa, który w oparciu o posiadaną wiedzę fachową i praktyczną znajomość stosunków międzyludzkich skutecznie zarządza wieloosobowym personelem. W głębszym sensie, często stosowanym w różnych religiach, mądrość oznacza zdolność do działania nacechowanego głębokim, emocjonalnym zaangażowaniem, zwiększającego w długiej perspektywie czasowej nie tylko dobro własne, ale też dobro ogólne. W tym sensie używa się tego terminu w takich zwrotach jak np. mądrość życiowa, czy mądrość rodzicielska. W obu tych znaczeniach mądrość wymaga nie tylko samej wiedzy, lecz także szeregu predyspozycji psychicznych, ale też duchowych i etycznych...


Źródło Wikipedia


Liczba wystąpień słów:
1. mądrość - występuje 6 razy w tekście
2. sensie - 3 razy
3. mądrości - 2 razy
...
umiejętność - 2 razy

Po przeanalizowaniu tekstu interesują nas tylko fragmenty – zdania z największą liczbą wystąpień powtarzających się słów.

Z tekst powinien zostać wybrany fragment,

jako pierwsze zdanie, priorytetowe słowo mądrość (występuje 2 razy – najwięcej w jednym zdaniu) i sensie (1 raz w zdaniu).

W tym sensie używa się tego terminu w takich zwrotach jak np. mądrość życiowa, czy mądrość rodzicielska.

i dalej

W tym sensie można np. mówić o mądrości nauczyciela, który wykorzystując swoją wiedzę pedagogiczną radzi sobie z kształceniem niesfornego ucznia, czy mądrości szefa, który w oparciu o posiadaną wiedzę fachową i praktyczną znajomość stosunków międzyludzkich skutecznie zarządza wieloosobowym personelem.

Z ograniczeniem długości wybranego tekstu np. do 3 zdań, albo może łatwiej do 500 znaków.

W jaki sposób tego dokonać?
Daiquiri
Może skorzystaj z str_word_count? Ewentualnie jak będziesz korzystał z implode() czy explode() czy ogólnie tablic to przyda się array_count_values
Malinaa
Funkcje zliczającą same słowa już napisałem wcześniej z wykorzystaniem array_count_values(), ale jak teraz wydobyć z tekstu tylko te zdania, w których znajdują się istotne dane - najczęściej występujące slowa i ułożyć je posortować w kolejności od zdania priorytetowego (z największą liczbą słów)?
pablo89pl
Moze taka prowizora coś nakieruje:

robisz sobie np explode po kropce i zapisujesz to do tablicy
indeks to numer zdania
  1. $zdania = explode('. ',$tekst);


nastepnie mozesz sobie jakos przeleciec podaną tablicę foreach'em
dla każdego tekstu robisz np znowu explode, tym razem po spacji
  1. $slowa = array();
  2. foreach($zdania as $key=>$zdanie)
  3. {
  4. $slowa[$key] = explode(' ',$zdanie);
  5. $scalowe_slowa = array_merge($slowa, $slowa[$key]);
  6. }

nastepnie zliczasz wystapienia http://pl2.php.net/manual/en/function.array-count-values.php
  1. $ile = array_count_value($scalone_slowa);

i masz tu ilosc wystapien kazdego slowa

dostosuj sobie podane przyklady do Twoich wymagań
Pisane z palca, powinno pomóc
Powodzenia
Malinaa
Obecnie mam coś takiego:

  1. <?php
  2.  
  3. $tekst = "Mądrość w najwęższym znaczeniu to umiejętność podejmowania uzasadnionych decyzji, które w dłuższej perspektywie przynoszą pozytywne rezultaty. W innym ujęciu można powiedzieć, że mądrość to umiejętność praktycznego wykorzystywania posiadanej wiedzy i doświadczenia. W tym sensie można np. mówić o mądrości nauczyciela, który wykorzystując swoją wiedzę pedagogiczną radzi sobie z kształceniem niesfornego ucznia, czy mądrości szefa, który w oparciu o posiadaną wiedzę fachową i praktyczną znajomość stosunków międzyludzkich skutecznie zarządza wieloosobowym personelem. W głębszym sensie, często stosowanym w różnych religiach, mądrość oznacza zdolność do działania nacechowanego głębokim, emocjonalnym zaangażowaniem, zwiększającego w długiej perspektywie czasowej nie tylko dobro własne, ale też dobro ogólne. W tym sensie używa się tego terminu w takich zwrotach jak np. mądrość życiowa, czy mądrość rodzicielska. W obu tych znaczeniach mądrość wymaga nie tylko samej wiedzy, lecz także szeregu predyspozycji psychicznych, ale też duchowych i etycznych...";
  4.  
  5. // Czysc
  6. $tekst = strip_tags($tekst);
  7.  
  8. // Wyjatki
  9. $szukaj = array('np.','....','...','..'); // mozna inaczej, powstaja bledy ?
  10. $zastap = array('np','','','');
  11.  
  12. $tekst_wyjatki = str_replace($szukaj, $zastap, $tekst);
  13.  
  14. // Zdania
  15. $zdania = explode('.', $tekst_wyjatki);
  16.  
  17. // Slowa
  18. $slowa = array();
  19.  
  20. foreach($zdania as $key => $zdanie) {
  21. // Tylko slowa, usun inne znaki ?
  22. // $zdanie = preg_replace('/[^a-zA-Z0-9 ]/i', '', $zdanie);
  23.  
  24. $slowa[$key] = explode(' ', trim($zdanie));
  25.  
  26. // Minimalna dlugosc slowa ?
  27. // if (strlen($slowa) > 5)
  28.  
  29. // $scalone_slowa = array_merge($slowa, $slowa[$key]);
  30. }
  31.  
  32. // $ile = array_count_values($slowa); // Blad !
  33.  
  34. echo '<pre>';
  35. // print_r($scalone_slowa); // cos nie tak ?
  36. print_r($slowa);
  37. echo '</pre>';
  38.  
  39. ?>


nie działa.

Można ten kod dopracować i otrzymać w wyniku oczekiwane zdania?
pablo89pl
mialeś z tego skorzystać i samemu coś wykombinować...
np:
  1. <?php
  2.  
  3. $tekst = "Mądrość w najwęższym znaczeniu to umiejętność podejmowania uzasadnionych decyzji, które w dłuższej perspektywie przynoszą pozytywne rezultaty. W innym ujęciu można powiedzieć, że mądrość to umiejętność praktycznego wykorzystywania posiadanej wiedzy i doświadczenia. W tym sensie można np. mówić o mądrości nauczyciela, który wykorzystując swoją wiedzę pedagogiczną radzi sobie z kształceniem niesfornego ucznia, czy mądrości szefa, który w oparciu o posiadaną wiedzę fachową i praktyczną znajomość stosunków międzyludzkich skutecznie zarządza wieloosobowym personelem. W głębszym sensie, często stosowanym w różnych religiach, mądrość oznacza zdolność do działania nacechowanego głębokim, emocjonalnym zaangażowaniem, zwiększającego w długiej perspektywie czasowej nie tylko dobro własne, ale też dobro ogólne. W tym sensie używa się tego terminu w takich zwrotach jak np. mądrość życiowa, czy mądrość rodzicielska. W obu tych znaczeniach mądrość wymaga nie tylko samej wiedzy, lecz także szeregu predyspozycji psychicznych, ale też duchowych i etycznych..";
  4. // Czysc
  5. $tekst = strip_tags($tekst);
  6.  
  7. // Wyjatki
  8. $szukaj = array('np.','....','...','..'); // mozna inaczej, powstaja bledy ?
  9. $zastap = array('np','','','');
  10.  
  11. $tekst_wyjatki = str_replace($szukaj, $zastap, $tekst);
  12.  
  13. // Zdania
  14. $zdania = explode('.', $tekst_wyjatki);
  15.  
  16. // Slowa
  17. $slowa = array();
  18. $scalone_slowa = array();
  19. foreach($zdania as $key => $zdanie) {
  20.  
  21. $slowa[$key] = explode(' ', trim($zdanie));
  22.  
  23. foreach($slowa[$key] as $slowko )
  24. {
  25. if (strlen($slowko) > 5) $scalone_slowa[] = $slowko."#".$key;
  26. }
  27.  
  28. }
  29.  
  30. $ile = array_count_values($scalone_slowa);
  31.  
  32. echo '<pre>';
  33. ksort($ile);
  34. print_r($ile);
  35. echo '</pre>';
  36.  
  37.  
  38.  

zwracaną masz tablice: słowo#numer_zdania => ilosc_wystapien
obrób sobie w sposób jaki tam sobie potrzebujesz
Malinaa
Szczerze mówiąc,
nie wiem jak z Twojego kodu wybrać tylko te potrzebne zdania,
ale z pomocą tego kodu, rozwiązałem zagadkę smile.gif

Tutaj robisz coś fajnego, ja zrobiłem to na swój sposób.
Jeżeli miałbyś czas dokończyć to super.

Podsumowując dziękuje za prezent Mikołajkowy dry.gif
pablo89pl
  1. <?php
  2.  
  3. $tekst = "Mądrość w najwęższym znaczeniu to umiejętność podejmowania uzasadnionych decyzji, które w dłuższej perspektywie przynoszą pozytywne rezultaty. W innym ujęciu można powiedzieć, że mądrość to umiejętność praktycznego wykorzystywania posiadanej wiedzy i doświadczenia. W tym sensie można np. mówić o mądrości nauczyciela, który wykorzystując swoją wiedzę pedagogiczną radzi sobie z kształceniem niesfornego ucznia, czy mądrości szefa, który w oparciu o posiadaną wiedzę fachową i praktyczną znajomość stosunków międzyludzkich skutecznie zarządza wieloosobowym personelem. W głębszym sensie, często stosowanym w różnych religiach, mądrość oznacza zdolność do działania nacechowanego głębokim, emocjonalnym zaangażowaniem, zwiększającego w długiej perspektywie czasowej nie tylko dobro własne, ale też dobro ogólne. W tym sensie używa się tego terminu w takich zwrotach jak np. mądrość życiowa, czy mądrość rodzicielska. W obu tych znaczeniach mądrość wymaga nie tylko samej wiedzy, lecz także szeregu predyspozycji psychicznych, ale też duchowych i etycznych..";
  4. // Czysc
  5. $tekst = strip_tags($tekst);
  6.  
  7. // Wyjatki
  8. $szukaj = array('np.','....','...','..',','); // mozna inaczej, powstaja bledy ?
  9. $zastap = array('np','','','');
  10.  
  11. $tekst_wyjatki = str_replace($szukaj, $zastap, $tekst);
  12.  
  13. // Zdania
  14. $zdania = explode('.', $tekst_wyjatki);
  15.  
  16. // Slowa
  17. $slowa = array();
  18. $scalone_slowa = array();
  19.  
  20.  
  21. foreach($zdania as $key => $zdanie) {
  22.  
  23. $slowa[$key] = explode(' ', trim($zdanie));
  24.  
  25. foreach($slowa[$key] as $slowko )
  26. {
  27. $slowko = mb_strtolower($slowko,'UTF-8');
  28. if (strlen($slowko) > 5)
  29. {
  30. $wszystkie_slowa[] = $slowko;
  31. if( !in_array($key, (array) $gdzie[$slowko] ) ) $gdzie[$slowko][] = $key; // tablica z numerami kazdego zdania
  32. }
  33. }
  34. }
  35.  
  36. $ile = array_count_values($wszystkie_slowa); // ilosc wystapien kazdego slowka
  37. arsort($ile);
  38.  
  39. $minimalna_ilosc_wystapien = 4; // ile wystapien minimum danego slowka
  40. $wybrane_zdania = array();
  41. foreach($ile as $slowo => $ilosc )
  42. {
  43. if( $ilosc < $minimalna_ilosc_wystapien ) break;
  44. $wybrane_zdania = array_merge($gdzie[$slowo], $wybrane_zdania);
  45. }
  46. $wybrane_zdania = array_unique($wybrane_zdania);
  47. echo '<pre>';
  48.  
  49. print_r($ile); // ktore slowko ile razy wystapilo
  50. print_r($gdzie); // ktore slowko w ktorym zdaniu wystapilo
  51. print_r($wybrane_zdania); // zdania ktore zawieraja slowka z iloscia w calym tekscie nie mniejsza niz $minimalna_ilosc_wystapien
  52.  
  53. asort($wybrane_zdania);
  54. foreach($wybrane_zdania as $id)
  55. {
  56. echo $zdania[$id].PHP_EOL;
  57. }
  58. echo '</pre>';
  59.  


zmodyfikuj sobie jak uwazasz, usun co zbedne, dodaj co potrzebne smile.gif
z tego co napisales chcialbys wybrac zdania z iloscia tych wybranych slow jak najwieksza
w takim razie musisz uzyc substr_count jakeis pętle na każdym zdaniu i zsumować wystąpienia tych słow w kazdym zdaniu i potem wybrac
wówczas musisz zmodyfikowac następującą pętlę:
  1. foreach($ile as $slowo => $ilosc )
  2. {
  3. if( $ilosc < $minimalna_ilosc_wystapien ) break;
  4. $wybrane_zdania = array_merge($gdzie[$slowo], $wybrane_zdania);
  5. }
Malinaa
Chyba zakumałem Twój kod.

To jednak było za wcześnie
//$wybrane_zdania = array_unique($wybrane_zdania);

//asort($wybrane_zdania);

ponieważ nie wyświetlało wyniku w oczekiwanej kolejności,
ustaliłem więc priorytety i teraz działa na 100% smile.gif

  1. // Priorytetowe zdania - tworzenie algorytmu
  2. $klucze = array_keys($ile);
  3. $slowo_one = $klucze[0]; // priorytetowe pierwsze slowo
  4. $slowo_two = $klucze[1];
  5. $slowo_three = $klucze[2];
  6.  
  7. $priorytetowe_zdania = array();
  8.  
  9. foreach($wybrane_zdania as $id) {
  10. $zdanie = $zdania[$id].PHP_EOL;
  11.  
  12. // Ustalenie priorytetu - pierwsze slowo (najwieksza liczba wystapien)
  13. $priorytet_one = preg_match_all("/$slowo_one/i", $zdanie, $wyjscie);
  14. $priorytet_two = preg_match_all("/$slowo_two/i", $zdanie, $wyjscie);
  15. $priorytet_three = preg_match_all("/$slowo_three/i", $zdanie, $wyjscie);
  16.  
  17. $priorytet_razem = $priorytet_one + $priorytet_two + $priorytet_three;
  18.  
  19. $ile_razem = $priorytet_razem.'#'.$id;
  20.  
  21. $priorytetowe_zdania[$ile_razem] = trim($zdanie).'. ';
  22. }
  23.  
  24. // Usun dupliaty wartosci
  25. $priorytetowe_zdania = array_unique($priorytetowe_zdania);
  26.  
  27. // Sortowanie
  28. krsort($priorytetowe_zdania);
  29.  
  30. // Wynik dzialania
  31. $ile_zdan = 3; // Maksymalna liczba zdan
  32.  
  33. foreach($priorytetowe_zdania as $id) {
  34. $i ++;
  35. if ($i <= $ile_zdan) $wynik .= $id;
  36. }
  37.  
  38. echo '<p>'.$wynik.'</p>';


zawsze są jednak jakieś wyjątki,
jest jeszcze jeden problem

// Wyjatki
$szukaj = array('np.','....','...','..',','); // mozna inaczej, powstaja bledy ?
$zastap = array('np','','','');
$tekst_wyjatki = str_replace($szukaj, $zastap, $tekst);

Pomysł na wyjątki?

Coś w rodzaju jeśli więcej niż jedna kropka ciąg = ''
i dla skrótów jeśli np. długość słowa przed kropką <= 3 znaki.
Noidea
Możesz przyjąć, że granica zdań jest tam, gdzie występuje wzorzec:
Kod
mała_litera kropka białe_znaki duża_litera

i użyć wyrażeń regularnych do rozbijania tekstu. Przykład 2 pokazuje, że rozwiązanie nie jest idealne smile.gif


  1. <pre>
  2. <?php
  3.  
  4. $example1 = "Mądrość w najwęższym znaczeniu to umiejętność podejmowania uzasadnionych decyzji, które w dłuższej perspektywie przynoszą pozytywne rezultaty. W innym ujęciu można powiedzieć, że mądrość to umiejętność praktycznego wykorzystywania posiadanej wiedzy i doświadczenia. W tym sensie można np. mówić o mądrości nauczyciela, który wykorzystując swoją wiedzę pedagogiczną radzi sobie z kształceniem niesfornego ucznia, czy mądrości szefa, który w oparciu o posiadaną wiedzę fachową i praktyczną znajomość stosunków międzyludzkich skutecznie zarządza wieloosobowym personelem. W głębszym sensie, często stosowanym w różnych religiach, mądrość oznacza zdolność do działania nacechowanego głębokim, emocjonalnym zaangażowaniem, zwiększającego w długiej perspektywie czasowej nie tylko dobro własne, ale też dobro ogólne. W tym sensie używa się tego terminu w takich zwrotach jak np. mądrość życiowa, czy mądrość rodzicielska. W obu tych znaczeniach mądrość wymaga nie tylko samej wiedzy, lecz także szeregu predyspozycji psychicznych, ale też duchowych i etycznych..";
  5. $example2 = "Skrótowce wykazują często właściwości odmienne od reszty słownictwa; wiele z nich ma na przykład akcent oksytoniczny (akcent końcowy, na ostatniej sylabie), np. AWS (Akcja Wyborcza Solidarność) [wymowa: awues], BBC (British Broadcasting Corporation) [wymowa: bibis-i].";
  6. $example3 = "Test zdań konczących się polską literą. Jakieś zdanie. Żdanie z polską literą na początku.";
  7.  
  8.  
  9. $pattern = "~(?<=\p{Ll}\.)\s+(?=\p{Lu})~u";
  10.  
  11. print_r( preg_split( $pattern, $example1 ) );
  12. print_r( preg_split( $pattern, $example2 ) );
  13. print_r( preg_split( $pattern, $example3 ) );
  14.  
  15. ?>
  16. </pre>



PS. Wyrażenie działa dla tekstu zakodowanego w UTF-8. Jeśli z jakiegoś powodu używasz kodowania iso/windows, to zamień \p{Ll} i \p{Lu} odpowiednio na [a-zążśźęćńół] i [A-ZĄŻŚŹĘĆŃÓŁ] i wywal modyfikator u
Malinaa
Tym sposobem mogłoby być i lepiej,
ale narazie przekłamuje.

Wyniki, zliczone słowa

// str_replace
[mądrość] => 6
[sensie] => 3
[wiedzy] => 2
[perspektywie] => 2
[wiedzę] => 2
[mądrości] => 2
[można] => 2
[który] => 2
[umiejętność] => 2

// pattern - preg_split ?
[mądrość] => 6
[można] => 2
[mądrości] => 2
[wiedzę] => 2
[perspektywie] => 2
[który] => 2
[sensie] => 2
[umiejętność] => 2

Dlaczego z użyciem pattern przekłamuje,
ponieważ bez str_replace np. wyraz 'sensie' występuje też z przecinkiem [sensie,] => 1
i wiele innych wyrazów podobnie.
Wyrażenie nie usuwa przecinka i innych znaków znajdujących się przed, za wyrazem.

Musiałoby być tutaj inne wyrażenie?
Noidea
Jeśli potrzebujesz tylko usunąć przecinki na końcach wyrazów, to robisz:
  1. $slowko = trim( $slowko, "," );


ale polecam oczyścić słowa ze wszelkiego śmiecia, które znajduje się na początku/końcu (nawiasy, przecinki, cyfry, dwukropki, itp.)
  1. // Usuwa wszystko co nie jest literą z początku i końca wyrazu
  2. $slowko = preg_replace( "~^[^\pL]+~u", "", $slowko );
  3. $slowko = preg_replace( "~[^\pL]+$~u", "", $slowko );



Teraz skrypt powinien spełniać twoje oczekiwania, ale nadal nie poradzi sobie ze wszystkimi przypadkami. Język polski nie jest językiem regularnym, więc nie da się go ogarnąć wyrażeniami regularnymi.
Malinaa
Teraz bez kombnacji jest oczekiwany wynik.
I to mi się podoba smile.gif
Może nie jest idealnie, ale jest bardzo dobrze.
Dzięki
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.