我写了找到某个最大质数的函数。此功能有效,但问题是它太慢。例如,当我输入600851475143作为参数时,找到最大素数的过程会持续太长时间。如何修改它以便使其更快地工作? 这是我的代码:
class test {
static addArray(someArray, member) {
for (var i = 0; i <= someArray.length; i++) {
if (i == someArray.length) {
someArray[i] = member;
return someArray;
}
}
}
static someLength(someArray) {
var i = 0;
while (someArray[i] !== undefined) {
var lastItem = i;
i++;
}
return i;
}
static testPrime(i) {
for (var k=2; k < i; k++) {
if (i % k == 0) {
return false;
}
}
return true;
}
}
var primeArray = [];
function largestPrime(n) {
for (var i=2; i < n; i++) {
//var k = n / i;
if (n % i == 0 && test.testPrime(i) == true) {
test.addArray(primeArray, i);
n == n / i;
}
}
return primeArray[test.someLength(primeArray) - 1];
}
document.write(largestPrime(600851475143));
答案 0 :(得分:1)
好的,在开始讨论之前,让我们先整理一下理论。数学上,用O(n)
表示法(big-o表示法)来表示度量特定代码运行所花费时间的方式,其中n
是输入的大小。
您的测试素数函数称为linear complexity
,这意味着随着n
的大小(在这种情况下,您的数字输入)变大,它将线性降低。
对于数字15
,执行上下文如下:
15 % 2 == 0 (FALSE)
15 % 3 == 0 (TRUE)
...
15 % 14 == 0 (FALSE)
这意味着对于数字100
,将有98(2-99)步。随着时间的流逝,它会增长。让我们考虑一下您的号码:600851475143
。该程序将执行600851475143
; for-loop
将被触发600,851,475,141
次。
现在,让我们考虑一个时钟周期。假设每条指令占用1 clock cycle
,而循环的简化版本需要2,则数字600851475143
将执行1,201,702,950,286
次。考虑到每个时钟周期花费0.0000000625
秒(对于Arduino这样的16 MHz平台),仅该代码花费的时间为:
0.0000000625 * 1201702950286 = ~75,106 seconds
或在20 hours
附近。
你知道我要去哪里。
使该程序更快运行的最佳方法是使用probabilistic test并使用该数字(或其BigInteger变体)确认您的发现。
从某种意义上来说,您的方法更加线性,for-loop
用于检查素数的迭代次数随着次数的增加而增加。您可以将CPU周期时间与数字一起绘制,您将意识到这是一种效率很低的方法。
我在我的大学里有离散数学,所以只有一个警告-当您进入越来越快的测试的乌托邦时,素数测试及其变体会变得非常混乱。这是一条充满数学荆棘的小路,骑车穿越丛林时应该系好安全带! ;)
如果您需要更多有关此方面的信息,我们将很乐意为您提供帮助!希望对您有所帮助! :)