Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [php] zmienna static
Forum PHP.pl > Forum > PHP
hhg
zmienna static nie spelnia mojego zalozenia bo zle ja stosuje, powinienem gdzies zerowac (tylko gdzie?) bo sumuje mi wyniki z poprzednich wywolan funkcji rekurencyjnej a w kolejnych wywolaniach na wejsciu otrzymuje wartosc static z dotychczasowych wywolan funkcji rekurencyjnej, czyli nie zeruje jej miedzy jednym wywolaniem a drugim.

efekt jest taki jak pod linkiem
nalezy zwrocic uwage na:
Cytat
- Euklidesa modulo iteracyjny ma zlozonosc 5 (...)
- Euklidesa modulo rekurencyjny ma zlozonosc 5 (...)


a za moment np.

Cytat
- Euklidesa modulo iteracyjny ma zlozonosc 6 (...)
- Euklidesa modulo rekurencyjny ma zlozonosc 11 (...)


swiadczy to o tym ze dodal nowe wyniki do starych i dostal 11...

gdzie powinienem to zerowac?

link do skryptu jest tutaj:


  1. <?php
  2.  
  3. include('funkcje.inc');
  4.  
  5.  
  6. // generowanie par losowych liczb o wspolnych przedzialach (po to aby wykazac fibonacciego)
  7.  
  8. $max = mt_getrandmax()+1;
  9.  
  10.  
  11. $operation = array();
  12.  
  13. // liczniki do zliaczania zlozonosci
  14. $m = 0;
  15. $n = 0;
  16.  
  17. for ($i=1; $i<=29; $i+=6)
  18. {
  19. for ($k=1; $k<=29; $k+=6)
  20. {
  21. $od_1 = pow(2,$i);
  22. $do_1 = pow(2,$i+6);
  23.  
  24. $od_2 = pow(2,$k);
  25. $do_2 = pow(2,$k+6);
  26.  
  27. // liczby losowe:
  28. $temp1 = abs(mt_rand($od_1,$do_1) + mt_rand($od_1,$do_1));
  29. $temp2 = abs(mt_rand($od_2,$do_2) + mt_rand($od_2,$do_2));
  30.  
  31. echo 'Dla liczb z zakresu:<br />'; 
  32. echo '- od ' . ($od_1 + $od_1) . ' (2^' . ($i+1) . ') do ' . ($do_1 + $do_1) . ' (2^' . ($i+7) . '), liczba losowa A = ' . $temp1 . '.<br />';
  33. echo '- od ' . ($od_2 + $od_2) . ' (2^' . ($k+1) . ') do ' . ($do_2 + $do_2) . ' (2^' . ($k+7) . '), liczba losowa B = ' . $temp2 . '.<br /><br />';
  34.  
  35.  
  36. // operacje na tych liczbach
  37. test($temp1,$temp2);
  38.  
  39.  
  40. }
  41. }
  42.  
  43. ?>


ale najważniejsze, czyli funkcja ze static tutaj:

chodzi o funkcje div_rek() i test() gdzie ta pierwsza jest wywolywana


co prawda w dif_rek jest to samo ale to pewnie jest konsekwencja tego ze korzysta z tej samej zmiennej $l ktorej nie zeruje..

pozdrawiam
Hacker
  1. <?php
  2. return $l;
  3. }
  4. ?>


Zamień na
  1. <?php
  2. $y = $l;
  3. $l = 0;
  4. return $y;
  5. }
  6. ?>
woolf864
poprostu zachowuj zmienne tylko do momentu kiedy sa potrzebne...
kiedy jakaś zmienna jest niepotrzebna daj
  1. <?
  2. unset($t);
  3. ?>

i to zwalnie pamięć...
no chyba że wszystkie zmienne w tym momencie są potrzebne to ja ci już nie poradze winksmiley.jpg
Hacker
na pewno optymalizacją będzie zmienienie funkcji znajdz_dzielniki na
  1. <?php
  2. function znajdz_dzielniki ($start)
  3. {
  4. $zakres = $start;
  5. $tab = array();
  6.  
  7. while($start % 2 == 0)
  8. {
  9. $start /= 2;
  10. if (!isset($tab[2]))
  11. $tab[2] = 0;
  12. $tab[2]++;
  13. }
  14. $i = 3;
  15. while ($i <= floor($start/2))
  16. { 
  17.  
  18. if ($start % $i == 0)
  19. {
  20. $start = $start/$i;
  21.  
  22. if (!isset($tab[$i]))
  23. $tab[$i] = 0;
  24.  
  25. $tab[$i]++;
  26.  
  27. if ($start % $i != 0)
  28. $i+=2;
  29. }
  30. else
  31. {
  32. $i+=2;
  33. }
  34. }
  35. if ($start != 1)
  36. $tab[$start] = 1;
  37.  
  38.  
  39. // for ($i=2; $i<= $zakres; $i++)
  40. // {
  41. //echo 'liczba i = ' . $i . ' pojawia sie ' . $tab[$i] . ' razy<br />';
  42. // }
  43.  
  44. unset($zakres); unset($start); unset($i);
  45.  
  46. return $tab;
  47. }
  48. ?>


i wtedy
Cytat
zoptymalizowana
liczba pierwsza 2999
czas wykonania: 0.09904
duża liczba 2984
czas wykonania: 0.02116
bez optymalizacji
liczba pierwsza 2999
czas wykonania: 0.51552
duża liczba 2984
czas wykonania: 0.32166


BTW. Po co piszesz takie matematyczne funkcje?
Do czego to będzie służyć?

EDIT: Pomyłka - zmiana if na while i pare innych w tym miejscu
hhg
z Twoich poprawek odnotowalem zakomentowanie petli wypisujacej (slusznie) ale nie wiem dlaczego zmieniles $i++;
na
$i+=2;

? to zmienia sens (chyba)

a moze cos jeszcze zmieniles?



ad BTW. pisze bo musze :/ to maja byc testy zlozonosci i kosztownosci algorytmow
Hacker
Zmieniłem, bo jak coś podzielisz przez 2^y lub nie (wszystko jedno), to nie będzie się dzieliło przez 2*x. I zmieniłem $i = 2 na $i = 3, a sprawdzanie, czy dzieli się przez 2, dałem statyczne w funkcji. Kolejna zmiana to $i <= $start na $i <= floor($start / 2), ponieważ dzielnikiem liczby na pewno nie jest liczba większa od jej połowy.

Optymalizacja ot co.
Hacker
Hmmmm...
U mnie działa, nie zacina się na tej pętli...
Spróbuj dodać do tej pętli echo $start; i zobacz czy się zmienia.
Hacker
Dodając warunek usunąłeś $tab[2]++;
  1. <?php
  2. while($start % 2 == 0 && $start !== 0)
  3. {
  4. $start /= 2;
  5. if (!isset($tab[2]))
  6. $tab[2] = 0;
  7. }
  8. ?>


  1. <?php
  2. if ( count($tab1) >= ($ile = count($tab2)) )
  3. {
  4. ...
  5. }
  6. ?>


Po co to?
Przecież już się upewniłeś, że $liczba1 > $liczba2
Bo po mojej optymalizacji może źle działać.

Zrób to tak.

  1. <?php
  2. $nwd = 1;
  3. $keys = (count[$tab1] > count($tab2)) ? array_keys($tab[2]) : array_keys($tab[1]);
  4. foreach ($keys as $i)
  5. {
  6. $l++;
  7. if ( $tab1[$i] && $tab2[$i] )
  8. if ( $tab1[$i] > $tab2[$i] )
  9. {
  10. $nwd *= $tab2[$i] * $i;
  11. }
  12. else
  13. {
  14. $nwd *= $tab1[$i] * $i;
  15. }
  16. }
  17. ?>


Źle liczysz też złożoność, bo funkcja fool_nwd wywołuje dwa razy funkcje znajdz_dzielniki(), która też wykonuje jakieś operacje... Z tych 2 funkcji można by zrobić jedną, przy okazji optymalizując (bez tablic - znajduje wspólne dzielniki dla obu liczb na raz)
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.