【问题标题】:Largest prime factor function works too slow最大素数函数工作太慢
【发布时间】:2019-02-14 00:37:36
【问题描述】:

我写了一个函数,它可以找到某个数的最大素数。此功能有效,但问题是它太慢了。例如,当我输入 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));

【问题讨论】:

  • 这是一个代码审查的好问题,而不是 StackOverflow。
  • @ChrisSharp 对于相对较小的数字,它的工作速度更快,我查看了代码,我认为没有额外的花括号。最后一个属于class

标签: javascript function primes


【解决方案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。程序将执行600851475143for-loop 将被触发 600,851,475,141 次。

现在,让我们考虑一个时钟周期。假设每条指令需要1 clock cycle,而循环的简化版本需要2,数字600851475143 将执行1,201,702,950,286 次。考虑每个时钟周期需要0.0000000625 秒(对于 16-MHz 平台,例如Arduino),仅该代码所用的时间是:

0.0000000625 * 1201702950286 = ~75,106 seconds

或在20 hours 附近。

你知道我要做什么了。

让这个程序更快运行的最佳方法是使用probabilistic test 并使用这个数字(或其 BigInteger 变体)确认您的发现。


您的方法更线性,因为for-loop 检查素数的迭代次数随着次数的增加而增加。您可以将 CPU 周期时间与数字一起绘制出来,您会发现这是一种相当低效的方法。

我在我的大学有离散数学,所以只是一个警告 - 当你进入越来越快的测试的乌托邦时,素数测试及其变体变得非常混乱。这是一条充满数学荆棘的道路,您应该在穿越丛林时系好安全带! ;)

如果您需要这方面的更多信息,我很乐意为您提供帮助!我希望这有帮助! :)

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2013-11-13
  • 2022-06-26
  • 2022-01-11
  • 1970-01-01
  • 1970-01-01
  • 2022-01-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多