寻找唯一除数的最优算法

时间:2012-04-08 07:20:11

标签: algorithm

我只是想到一个似乎并不太难的问题但是当我们想到最佳地做这件事时,它就变成了一个很好的问题。问题是 - 我们得到了一个数字列表(数组)和一个数字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 :(得分:0)

一个明显的优化如下:做sieve of eratosthenes来强制所有数字,直到您知道的值高于您给出的列表中的任何一个。现在,您可以从该列表中迭代给定数字的所有因子。

接下来你要做的是:对于列表中的每个数字及其每个素因子p,你应该将N除以p,直到它被它整除。在你这样做之后,你正在寻找的除数都是余数的除数。

希望这有帮助。