【问题标题】:optimal algorithm for finding unique divisors寻找唯一除数的最佳算法
【发布时间】:2014-06-06 00:37:57
【问题描述】:

我只是在想一个似乎并不难的问题,但是当我们考虑以最佳方式完成它时,它就变成了一个很好的问题。问题是 - 我们得到了一个数字列表(数组)和一个数字 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;
}

【问题讨论】:

  • 请您在这里展示您的努力。

标签: algorithm


【解决方案1】:

一个明显的优化如下 - 执行sieve of eratosthenes 将所有数字分解为一个您知道的值,该值高于您给出的列表中的任何单个值。现在您可以从该列表中迭代给定数字的所有因子。

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

希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多