2008-11-30 7 views
4

J'ai un tableau associatif, à savoirComment stocker et réinitialiser un pointeur de tableau PHP?

$primes = array(
    2=>2, 
    3=>3, 
    5=>5, 
    7=>7, 
    11=>11, 
    13=>13, 
    17=>17, 
    // ...etc 
); 

alors je ne

// seek to first prime greater than 10000 
reset($primes); 
while(next($primes) < 10000) {} 
prev($primes); 

// iterate until target found 
while($p = next($primes)) { 
     $res = doSomeCalculationsOn($p); 

     if(IsPrime($res)) 
      return $p; 
} 

Le problème est que ISPRIME boucles aussi à travers le tableau des nombres premiers $,

function IsPrime($num) { 
    global $primesto, $primes, $lastprime; 

    if ($primesto >= $num) 
     // using the assoc array lets me do this as a lookup 
     return isset($primes[$num]); 

    $root = (int) sqrt($num); 
    if ($primesto < $root) 
     CalcPrimesTo($root); 

    foreach($primes as $p) {  // <- Danger, Will Robinson! 
     if($num % $p == 0) 
      return false; 

     if ($p >= $root) 
      break; 
    } 

    return true; 
} 

qui Trashes le tableau pointeur Je suis en train de répéter.

J'aimerais pouvoir enregistrer et restaurer le pointeur interne de la baie dans la fonction IsPrime() afin qu'il n'ait pas cet effet secondaire. Est-ce qu'il y a un moyen de faire ça?

+0

+1 pour Danger, Will Robinson! – n0nag0n

Répondre

4

Ne comptez pas sur les pointeurs de tableau. Utilisez plutôt des itérateurs.

Vous pouvez remplacer votre code externe avec:

foreach ($primes as $p) { 
    if ($p > 10000 && IsPrime(doSomeCalculationsOn($p))) { 
    return $p; 
    } 
} 
+0

(front claquant) OK, cela fonctionne - je pensais foreach() utilisé le propre pointeur de la matrice, mais apparemment pas. Il * réinitialise le pointeur interne du tableau, ce qui est un effet secondaire étrange? –

+0

Je ne suis pas sûr de savoir comment fonctionne l'implémentation interne de foreach, mais il maintient son propre état.Je ne me souviens pas d'avoir jamais utilisé des pointeurs de tableau pour parcourir des listes en PHP. – troelskn

+0

Btw. C'est un peu étrange d'utiliser un tableau assoc pour vos valeurs. J'utiliserais une liste simple, puis j'utiliserai in_array() pour vérifier si une valeur existe. – troelskn

4

Vous pouvez « sauver » l'état du tableau:

$state = key($array); 

et « restaurer » (ne sais pas s'il y a une meilleure méthode):

reset($array); 

while(key($array) != $state) 
    next($array); 
+0

Um ... le bon effet, mais c'est O (n) dans la taille du tableau, ce qui rend mon algorithme O (n^2) inacceptable. Je me demande comment il serait difficile d'étendre la réinitialisation ($ arr, $ key = 0)? (Réinitialiser pour démarrer ou pour la valeur-clé spécifiée?) –

+0

Cette réponse n'est peut-être pas une "meilleure pratique", mais c'est la bonne réponse à la question, ... imo. – aurora

0

Si la vitesse est pas un problème et vous n'êtes pas en train de pousser les limites de la mémoire php, la solution la plus rapide consiste simplement à dupliquer votre matrice de nombres premiers et à en itérater 2 différentes.

$awesomePrimes=$primes; 

changer ensuite et globals foreach dans votre fonction $awesomePrimes

+0

Pour un tableau contenant 2 millions d'éléments, qui utilise 68 Mo de mémoire supplémentaire - pas la fin du monde, mais semble inutile. –

0

Que diriez-vous de faire un plus éventail de int -> int, où l'indice est un nombre en cours d'exécution 0-n et la valeur est l'indice de la tableau associatif? Donc, vous auriez:

$pointer = array(
    0 => 2, 
    1 => 3, 
    2 => 5, 
    // ... 
); 

et au lieu de se référer directement à $prime que vous utilisez $prime[$pointer[$i]], ou quelque chose de similaire?

0

utilisez une boucle "for" pour l'une de vos itérations. par exemple utiliser cette boucle dans votre méthode de ISPRIME:

$primesLength = count($primes); // this is to avoid calling of count() so many times. 
for ($counter=0 ; $counter < $primesLength ; $counter++) { 
    $p = $primesLength[$counter]; 
    if($num % $p == 0) 
      return false; 

    if ($p >= $root) 
      break; 
} 

cette façon le pointeur de tableau interne ne sera pas utilisée dans la méthode.

Questions connexes