计算整数的所有因子的最快算法是什么?

时间:2013-03-29 04:07:01

标签: c algorithm numbers factors

我已经编写了这段代码但是它耗费了大量的时间来计算...... 你能帮我找到一种有效的方法吗?

int tag;
int* factors(int n)
{
    int a[1000000];
    for(int i=1;i<=n/2;i++)
        if(n%i==0)
            a[++tag]=i;
    a[++tag]=n;
    return(a);
}

这种蛮力方法在复杂性方面非常沉重...... 这个问题有没有更好的可行解决方案?

1 个答案:

答案 0 :(得分:7)

到目前为止,还没有人提出更快的算法。这并不一定意味着没有,因为另一方面它也没有被证明不可能更快地完成它。

您可能需要考虑的一个优化是,当达到sqrt(n)时,您无需搜索最多n / 2即可停止。

...如果您真的想要返回已经在&#34; chris&#34;中提到的所有候选人的列表,请务必为您的号码选择不同的存储位置。评价。

编辑:

正如我所说的那样,可用的算法种类繁多,在时间复杂度方面可能会比你提出的算法运行速度稍快一点,可能会表示添加更多的单词而不是给出的简短评论上方。

除了最明显的可能性是通过在首先将其分为奇数后以2步为单位运行循环来保证一些计算时间,还有一些其他技巧可用我没有提到它们基本上在上面给出的答案中更快。

导致这一决定的主要原因是,虽然例如将迭代次数减少2倍似乎是一个很大的胜利,与运行时的预期增长相比,随着数量的增加而增加一个常数项变得如此之小,以至于在复杂性理论中,甚至根本没有任何差别,两种算法都被认为具有(几乎)相同的时间复杂度。

即使有可能获得原始算法运行时间数百十亿次的常数增益,但两者之间仍然没有任何区别。

数字越大,对任何常数的影响就越小,如果它在你运行时的数字幅度也快速增长的情况下,你可以根据运行时间进行成像。

时间复杂度方面的一个非常特殊的障碍通常被视为实际上可行且仅仅是不可能的边界,即所谓的polynomial运行时间。

这意味着除此之外,即使运行时可能随着n的增长而急剧增长,仍然可以用常量指数k来描述这种增长,这样运行时是n^k左右。

另一方面,没有polynomial运行时间的算法无法用任何指数进行测量,你可能想要做多大的算法。

举一个例子,为什么这个差异可能真的很重要,让我们来看看两个想象的算法。第一个具有多项式运行时,比如说n^10而另一个运行时使用运行时n!说这个。

虽然对于小数字来说似乎并不坏,但我们假设n只有10个算法,算法一个需要10^10 = 10000000000个时间单位,而只有3628800个单位我们的第二个算法似乎运行得更快。

我们的算法二的问题是,与算法一相比,它的运行时间会急剧增长。在n=100,对于算法1,您会得到类似于100000000000000000000的内容,而对于算法2,它已经类似于93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000

使用n=1000进一步推动前沿,我们最终得到:1000000000000000000000000000000处的算法1,而我们的第二种算法将采用类似402387260077093773543702433923003985719374864210714632543799910429938512398629020592044208486969404800479988610197196058631666872994808558901323829669944590997424504087073759918823627727188732519779505950995276120874975462497043601418278094646496291056393887437886487337119181045825783647849977012476632889835955735432513185323958463075557409114262417474349347553428646576611667797396668820291207379143853719588249808126867838374559731746136085379534524221586593201928090878297308431392844403281231558611036976801357304216168747609675871348312025478589320767169132448426236131412508780208000261683151027341827977704784635868170164365024153691398281264810213092761244896359928705114964975419909342221566832572080821333186116811553615836546984046708975602900950537616475847728421889679646244945160765353408198901385442487984959953319101723355556602139450399736280750137837615307127761926849034352625200015888535147331611702103968175921510907788019393178114194545257223865541461062892187960223838971476088506276862967146674697562911234082439208160153780889893964518263243671616762179168909779911903754031274622289988005195444414282012187361745992642956581746628302955570299024324153181617210465832036786906117260158783520751516284225540265170483304226143974286933061690897968482590125458327168226458066526769958652682272807075781391858178889652208164348344825993266043367660176999612831860788386150279465955131156552036093988180612138558600301435694527224206344631797460594682573103790084024432438465657245014402821885252470935190620929023136493273497565513958720559654228749774011413346962715422845862377387538230483865688976461927383814900140767310446640259899490222221765904339901886018566526485061799702356193897017860040811889729918311021171229845901641921068884387121855646124960798722908519296819372388642614839657382291123125024186649353143970137428531926649875337218940694281434118520158014123344828015051399694290153483077644569099073152433278288269864602789864321139083506217095002597389863554277196742822248757586765752344220207573630569498825087968928162753848863396909959826280956121450994871701244516461260379029309120889086942028510640182154399457156805941872748998094254742173582401063677404595741785160829230135358081840096996372524230560855903700624271243416909004153690105933983835777939410970027753472000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000的算法。

如果你不相信自己计算它。 bc手册甚至包含了如何实现阶乘函数的示例。

但在数字计数时不要头晕目眩...... 可能有趣的是要知道有多少尾随零,我们必须添加到10以获得将宇宙年龄乘以得到如此大的时间跨度的因子,即使我们以普朗克时间为单位进行测量也是如此。不幸的是,我不知道。

有趣的是,到目前为止还没有任何已知的算法可以在polynomial时间内执行分解。

由于它不仅是一个有趣的研究领域本身,实用分解大整数的不可能性也在今天广泛使用的RSA公钥加密算法中起着重要作用,所以几乎很自然地,这个领域已经有很多研究。

发现算法(不破坏已经提及的障碍)比你想要的算法更快地运行 sligthly

As&#34; Jim Balter&#34; alredy在他的评论中正确注释你可能想看看引用的文章(参见:http://en.wikipedia.org/wiki/Integer_factorization#General-purpose),看看其他人已经提出的方法。

这篇文章也提到了#34; Jim&#34;可能是另一个有趣的资源:(见:What is the fastest factorization algorithm?

另一个值得关注的有趣链接可能是过去几年的RSA保理挑战赢家的名单,以某种方式了解今天可行和几乎不可能之间的边界。 (http://en.wikipedia.org/wiki/RSA_Factoring_Challenge