找到独特除数的有效方法

时间:2012-04-08 09:41:00

标签: php algorithm numbers primes

  

可能重复:
  optimal algorithm for finding unique divisors

我之前已经问过这个问题,但现在无法访问该帐户,所以我再次要求它再次展示我的努力。

给定一个数字列表(数组)和一个数字N,找到N的所有除数,它不会划分属于该列表的任何数字。我用蛮力和一种有效的方法解决了它(但不是最好的方法)。所以,我正在寻找一种最能解决这类问题的方法。一切都是整数(没有浮点)。

我的方法是首先找到数字N的所有除数(没有任何开销)。然后,我按相反的顺序(单独)对列表和除数进行排序。现在,对于每个除数D,我检查它是否除以列表中的任何数字(从最高元素开始直到一个元素,即> =除数D)。如果它分裂,那么D的所有除数也必须除。然后我从除数列表中删除这些元素,这些除数也是D的除数(可以认为是除去交点)。因此,最终左边的除数数组是必需的数组(根据我的方法)。如果有人可以指出我的方法中的任何错误或任何缺乏效率,我们将不胜感激。列表中可以出现的最大值是10 ^ 18。

我已经用PHP实现了它。我在下面提供我的代码。请忽略这些评论。

while($div=each($divisors))
{
$i=0;
$divisor=$div['key'];
//echo "divisor is $divisor\n";
while((int)$unfriendly[$i]>=$divisor)
{//echo "aya\n";
    if(!((int)bcmod($unfriendly[$i],$divisor)))
    {//echo "ayeea\n";
        $divisors_of_divisor=divisors_of_a_number($divisor);
        //print_r($divisors_of_divisor);
        //print_r($divisors);
        foreach($divisors_of_divisor as $d)
        unset($divisors[$d]);
        //print_r($divisors);
        break;
    }
    ++$i;
}
 }
echo sizeof($divisors);
function divisors_of_a_number($n)//returns all the divisors of a number in an unsorted array
{
$i=1;
$s=sqrt($n);
while($i<=$s)
{
if(!($n%$i))
{
    $a[]=$i;
    if($i!=$s)
    $a[]=$n/$i;
}
++$i;
}
return $a;
}
function divisors_of_a_number_as_keys_of_array($n)//returns all the divisors of a number in an unsorted array as keys
{
$i=1;
$s=sqrt($n);
while($i<=$s)
{
if(!($n%$i))
{
    $a[$i]=1;
    //if($i!=$s)
    $a[$n/$i]=1;
}
++$i;
}
return $a;
}

1 个答案:

答案 0 :(得分:1)

您可以使用此PHP implementation of the sieve of Eratosthenes

还有this

this

看看this question