为什么第二种解决方案比第一种更快?

时间:2016-03-03 09:23:32

标签: recursion time-complexity code-complexity

第一

boolean isPrime(int n) {
    if (n < 2)
        return false;
    return isPrime(n, 2);
}

private boolean isPrime(int n, int i) {
    if (i == n)
        return true;
    return (n % i == 0) ? false : isPrime(n, i + 1);
}

第二

boolean isPrime(int n) {
    if (n < 0) n = -n;
    if (n < 2) return false;
    if (n == 2) return true;
    if (n % 2 == 0) return false;

    return rec_isPrime(n, 3);
}

boolean rec_isPrime(int n, int div) {
    if (div * div > n) return true;
    if (n % div == 0) return false;
    return rec_isPrime(n, div + 2);
}

请解释为什么第二种解决方案比第一种更好。我在考试中提供了第一个解决方案,并且根据声称该解决方案无效的说法,我的意见得到了改进。我想知道什么是大不同

2 个答案:

答案 0 :(得分:1)

所以这是一个测试问题,我总是记住一些教授有一个丰富多彩的特权,但我可以看到一些理由可能会声称第一更慢:

  • 在计算素数时,你真的只需要测试另一个质数是否是因子。 第二个所以种子有一个奇数,3,然后加上2个递归调用,它会跳过检查均衡因子并减少一半所需的调用次数。

  • 正如@uselpa所指出的,第二代码段在测试因子的平方大于n时停止。在这个版本中,有效地意味着1和n之间的所有奇数都被考虑在内。这允许推导n比素数第一更快,在声明素数之前一直计算到n。

  • 可能会争辩说,由于第一次测试了递归函数内部的均匀而不是像 second 这样的外部方法,所以它是一个不确定的方法调用堆栈。

  • 我似乎也有人声称三元操作比if-else检查慢,所以你教授可能会陷入这种信念。 [就个人而言,我不相信存在性能差异。]

希望这会有所帮助。考虑一些素数很有趣!

答案 1 :(得分:0)

第一个解决方案的复杂度为O(n),因为它需要线性时间,第二个解决方案需要O(sqrt(n)),因为这行代码:if (div * div > n) return true;,因为要查找除数超过平方根不是必需的。有关详细信息,请查看:Why do we check up to the square root of a prime number to determine if it is prime?