项目欧拉12:具有500除数的三角数

时间:2013-05-18 04:58:25

标签: java

我正在阅读MathBlog上的Project Euler Problem 12的解决方案,我在理解代码背后的逻辑时遇到了一些麻烦。该程序使用素数因子分解来找到三角形数的除数。

private int PrimeFactorisationNoD(int number, int[] primelist) {
    int nod = 1;
    int exponent;
    int remain = number;

    for (int i = 0; i < primelist.Length; i++) {
        // In case there is a remainder this is a prime factor as well
        // The exponent of that factor is 1
        if (**primelist[i] * primelist[i] > number**) {
            return nod * 2;
        }

        exponent = 1;
        while (remain % primelist[i] == 0) {
            exponent++;
            remain = remain / primelist[i];
        }
        nod *= exponent;

        //If there is no remainder, return the count
        if (remain == 1) {
            return nod;
        }
    }
    return nod;
}

除了突出显示的部分“primelist [i] * primelist [i]&gt; number”之外,我理解程序的大部分内容。我无法理解这行代码的必要性。我将用一个例子来说明我的观点。假设我有一个数字510 = 2 * 3 * 5 * 17。突出显示的代码仅在Primelist转到第23位时才为真。但是当列表转到数字17时,条件保持== 1将为真且程序将退出循环。如果我将代码更改为if(保持== primelist [i])会更好吗,因为当primelist转到17而不是21时,循环将结束?

2 个答案:

答案 0 :(得分:2)

if条件在某些情况下加速代码(虽然它应该“保留”代替“数字”)。一旦达到primelist [i],我们就知道剩余的不能被primelist [0]到primelist [i-1]整除。如果primelist [i] ^ 2&gt;仍然存在,那么我们可以得出结论,仍然是primelist [i]和primelist [i] ^ 2-1(包括)之间的一些素数,好像是= ab然后a,b都必须是至少primelist [i]所以保持至少是primelist [i] ^ 2,这是一个矛盾。因此,我们可以停止搜索划分剩余的素数。

对于速度更快的示例,请取数= 7。然后当我们达到3(因为3 ^ 2 = 9> 7)时触发条件,所以我们不需要检查所有素数到7。

答案 1 :(得分:0)

首先,最好使用remain

primelist[i] * primelist[i] > remain

这是一种优化,因为remainremain的平方根之间不存在除数,所以你只剩下因子remain

此外,变量名exponent正在撒谎,它实际上包含指数加1。最好将其初始化为零并乘以exponent + 1