4

私は連想配列を持っています、すなわち

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

それから私はします

// 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;
}

問題は、IsPrimeも$primes配列をループすることです。

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;
}

これは、繰り返し処理している配列ポインタを破棄します。

この副作用が発生しないように、IsPrime()関数で配列の内部ポインターを保存および復元できるようにしたいと思います。これを行う方法はありますか?

4

5 に答える 5

5

配列の状態を「保存」できます。

$state = key($array);

そして「復元」(より良い方法があるかどうかはわかりません):

reset($array);

while(key($array) != $state)
    next($array);
于 2008-11-30T03:23:40.393 に答える
4

配列ポインターに依存しないでください。代わりに反復子を使用してください。

外部コードを次のものに置き換えることができます。

foreach ($primes as $p) {
  if ($p > 10000 && IsPrime(doSomeCalculationsOn($p))) {
    return $p;
  }
}
于 2008-11-30T10:22:34.570 に答える
0

速度が問題ではなく、php のメモリ制限を押し上げていない場合、素数配列を複製して 2 つの異なる配列を反復処理するのが最も簡単な解決策です。

$awesomePrimes=$primes;

次に、関数のグローバルと foreach を次のように変更します。$awesomePrimes

于 2008-11-30T04:56:58.427 に答える
0

int -> intインデックスが 0 からnまでの実行番号であり、値が連想配列のインデックスである の配列をもう 1 つ作成するのはどうですか? したがって、次のようになります。

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

直接参照する代わりに、または同様のもの$primeを使用しますか?$prime[$pointer[$i]]

于 2008-11-30T10:58:11.473 に答える
0

反復の 1 つに「for」ループを使用します。たとえば、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;
}

この方法では、内部配列ポインターはメソッドで使用されません。

于 2008-11-30T12:31:36.840 に答える