保理号码

时间:2010-08-27 09:31:04

标签: c++ algorithm math algebra

我有一个小于500,000,000的数字,我想以有效的方式对其进行分解。你建议用什么算法?注意:我有0.01秒的时间限制!

我刚刚编写了这个C ++代码,但它非常糟糕!

void factorize(int x,vector<doubly> &factors)
{
  for(int i=2;i<=x;i++)
    {
      if(x%i==0)
    {
      doubly a;
      a.number=i;
      a.power=0;
      while(x%i==0)
        {
          a.power++;
          x/=i;
        }
      factors.push_back(a);
    }
    }
}

并且加倍是这样的:

struct doubly
{
  int number;
  int power;
//and some functions!!

};

另一点:我知道n不是素数

5 个答案:

答案 0 :(得分:1)

您可能知道,分解是一个难题。您可能也知道您只需要测试与素数的可分性。一个小但众所周知的提示:你只需要测试n的平方根。我把理由留给你了。

看看Eratosthenes的筛子。也许你在these questions and answers找到了提示? that one怎么样?

如果你想更快地实现这一点 - 没有this answer的空间/时间的全部交易 - 提前计算所有素数到500,000,000的平方根并将它们放入一个数组中。显然,当上限增长时,这会被打破;)

答案 1 :(得分:0)

答案 2 :(得分:0)

事先将所有整数分解为500,000,000(无论如何)并将因子存储在数据库或固定长度记录格式中。您的查找速度很快,数据库应该适合现代PC。

这是时间/空间权衡的一端,但你没有说出你想要优化的内容。

或者,查看GNU coreutils“factor”的算法。

答案 3 :(得分:0)

您可以尝试使用Pollard的rho启发式算法,它适用于除数相对较小的复数:

Pollard's rho

答案 4 :(得分:0)

如果这是家庭作业,我相信你应该重新阅读你的讲义材料。

无论如何,你知道你的号码是复合的,非常小,没关系。

对于所有数字的天真试验,你最多需要sqrt(500000000)测试 - 对于最坏情况,这大约是22360次。你可以明显地跳过偶数,因为它们可以被2整除(先检查一下)。那么这将成为11180分,持续0.01秒。如果您的计算机每秒可以执行1.1 M分区,那么您可以使用天真的方法。

或者,您可以离线填写素数列表,最高可达sqrt(500M),然后尝试各自。这将进一步减少分歧。

或者,如果因素相距不太远,你可以尝试费马的方法。

如果这些不起作用,你可以尝试使用Pollard的rho和其他人。

或者,如果这不是作业,重述问题以解决限制(正如一些人所建议的那样,你是否可以事先预先计算出因素数字等)。