Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP]Zliczanie powtórzeń w tablicy
Forum PHP.pl > Forum > Przedszkole
Lopmer
Sytuacja wygląda następująco:

Dane są 2 tablice: $tab_lista oraz $tab_all

Obie tablice są jednowymiarowe i przechowują stringi. Jedyna różnica pomiędzy nimi polega na tym, że $tab_all posiada wiele zdublowanych wartości. Na czym polega problem ? Na tym, aby zliczyć ile powtórzeń poszczególnych wartości z tablicy pierwszej, znalazło się w tej drugiej. Wynikiem ma być tablica zawierająca wszystkie elementy $tab_lista z przyporządkowaną do nich liczbą powtórek (0 również wyświetlamy).

Pomyślałem, że dobrym pomysłem byłoby uzycie funkcji array_count_values na $tab_all, gdyż dokładnie czegoś takiego potrzebuje. Pojawił się jednak problem, gdyż wynikiem jest tablica posiadająca nadmiar danych (przypominam, że interesują mnie tylko elementy z $tab_lista).

Mój kod wygląda następująco:

  1. $file_in1 = 'lista.csv';
  2. $file_in2 = 'linki_2.csv';
  3.  
  4. $tab_lista=file($file_in1);
  5.  
  6. $tab2=file($file_in2);
  7. $tab_linki=array_count_values($tab2);
  8.  
  9. $wynik = array_intersect ($tab_lista, $tab_linki);
  10.  
  11. print_r($wynik);


Niestety pomysł z przecięciem tablic jest chyba średnio dobry, a w dodatku zapewne robię coś nie tak, bo wynikiem powyższego kodu jest pusta tablica. Tutaj wielka prośba do Was. Jako, że zacząłem bawić się w PHP dopiero 2 dni temu, nie mam pojęcia jak ten problem rozwiązać. Będę wdzięczny za każdą wskazówkę. Z góry wielkie dzięki winksmiley.jpg
Kroolik1
Pierwsza rzecz jaka wpadła mi do głowy to 2 pętelki...:
  1. $file_in1 = 'lista.csv';
  2. $file_in2 = 'linki_2.csv';
  3.  
  4. $tab_lista=file($file_in1);
  5.  
  6. $tab2=file($file_in2);
  7. $tab_linki=array_count_values($tab2);
  8.  
  9. for($a = 0; $a < count($tab_lista); a++){
  10.  
  11. $wynik[$tab_lista[$a]] = 0;
  12. for($b = 0; $b < count($tab_linki); b++){
  13.  
  14. if($tab_lista[$a] == $tab_linki[$b]){
  15.  
  16. $wynik[$tab_lista[$a]]++;
  17.  
  18. }
  19. }
  20. }
  21.  
  22. //$wynik = array_intersect ($tab_lista, $tab_linki);
  23.  
  24. print_r($wynik);
  25.  


ew.
  1. $file_in1 = 'lista.csv';
  2. $file_in2 = 'linki_2.csv';
  3.  
  4. $tab_lista=file($file_in1);
  5.  
  6. $tab2=file($file_in2);
  7. $tab_linki=array_count_values($tab2);
  8.  
  9. foreach($tab_lista as $value_lista){
  10.  
  11. $wynik[$value_lista] = 0;
  12. foreach($tab_linki as $value_linki{
  13.  
  14. if($value_lista == $value_linki){
  15.  
  16. $wynik[$value_lista]++;
  17.  
  18. }
  19. }
  20. }
  21.  
  22. //$wynik = array_intersect ($tab_lista, $tab_linki);
  23.  
  24. print_r($wynik);
  25.  
Zyx
To, co podałeś, to tzw. brute-force, czyli sprawdzanie wszystkiego na wszystkim. Polecam sprawdzić, ile czasu zajmie wykonanie tego algorytmu dla np. 1000 elementów smile.gif.

Znam co najmniej dwa znacznie lepsze algorytmy:

  1. $tab_lista = array_fill_keys($tab_lista, 0);
  2. foreach($tab_all as $element)
  3. {
  4. if(isset($tab_lista[$element]))
  5. {
  6. $tab_lista[$element]++;
  7. }
  8. }


Algorytm jest prosty - mamy strukturę $tab_lista z parami element => licznik. Struktura ta musi charakteryzować się szybkim czasem dostępu do elementu o podanym kluczu, a ten warunek spełniają tablice PHP (stąd kod w PHP jest taki prosty). Przelatujemy $tab_all i jeśli pojawia się w drugiej tablicy, to zwiększamy mu licznik wystąpień. Jedynie na początku musimy zamienić wartości na klucze w $tab_lista i zainicjować wszystko wartościami 0, a to robi funkcja array_fill_keys()

Drugi algorytm polega na posortowaniu $tab_all - wtedy wszystkie identyczne elementy znajdą się obok siebie i wystarczy je po prostu zliczyć, na co wystarczy jedna pętla puszczona raz po całej tablicy. Jednak w przypadku PHP chyba bardziej się opłaca zastosować poprzedni.
Lopmer
Wielkie dzięki za pomoc winksmiley.jpg
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.