Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [PHP]Zliczanie powtórzeń w tablicy
Lopmer
post
Post #1





Grupa: Zarejestrowani
Postów: 11
Pomógł: 0
Dołączył: 4.09.2009

Ostrzeżenie: (0%)
-----


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
Go to the top of the page
+Quote Post
Kroolik1
post
Post #2





Grupa: Zarejestrowani
Postów: 5
Pomógł: 1
Dołączył: 19.10.2009

Ostrzeżenie: (0%)
-----


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.  


Ten post edytował Kroolik1 24.10.2009, 10:21:16
Go to the top of the page
+Quote Post
Zyx
post
Post #3





Grupa: Zarejestrowani
Postów: 952
Pomógł: 154
Dołączył: 20.01.2007
Skąd: /dev/oracle

Ostrzeżenie: (0%)
-----


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.

Ten post edytował Zyx 24.10.2009, 13:15:04


--------------------
Specjalista ds. głupich i beznadziejnych, Zyx
Nowości wydawnicze: Open Power Collector 3.0.1.0 | Open Power Autoloader 3.0.3.0
Go to the top of the page
+Quote Post
Lopmer
post
Post #4





Grupa: Zarejestrowani
Postów: 11
Pomógł: 0
Dołączył: 4.09.2009

Ostrzeżenie: (0%)
-----


Wielkie dzięki za pomoc winksmiley.jpg

Ten post edytował Lopmer 24.10.2009, 20:55:33
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 22.08.2025 - 09:05