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的运行数字,值是关联数组的索引?因此,您将拥有:

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

而不是直接指代$prime您,而是使用$prime[$pointer[$i]], 或类似的东西?

于 2008-11-30T10:58:11.473 回答
0

为您的一次迭代使用“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 回答