Java Project Euler 12:带500个除数的三角形数

Java Project Euler 12:带500个除数的三角形数,java,Java,我在MathBlog上阅读了ProjectEuler问题12的解决方案,在理解代码背后的逻辑时遇到了一些困难。该程序使用素数分解来查找三角形数的除数 private int PrimeFactorisationNoD(int number, int[] primelist) { int nod = 1; int exponent; int remain = number; for (int i = 0; i < primelist.Length; i++)

我在MathBlog上阅读了ProjectEuler问题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;
}
private int primefactoriationnod(int number,int[]primelist){
int nod=1;
整数指数;
int=数字;
for(int i=0;i编号**){
返回nod*2;
}
指数=1;
while(保持%primelist[i]==0){
指数++;
剩余=剩余/基本列表[i];
}
nod*=指数;
//如果没有余数,则返回计数
如果(保持==1){
回首点头;
}
}
回首点头;
}

除突出显示的部分“primelist[I]*primelist[I]>编号”外,我了解程序的大部分内容。我很难理解这行代码的必要性。我将用一个例子来说明我的观点。假设我有一个数字510=2*3*5*17。只有当Primelist转到数字23时,突出显示的代码才会为真。但当列表转到17号时,条件remain==1将为真,程序将退出循环。如果我将代码更改为if(reside==primelist[I]),会更好吗?因为当primelist转到数字17而不是21时,循环将结束

在某些情况下,if条件会加快代码的速度(尽管它应该用“resident”代替“number”)。一旦到达素数表[i],我们就知道剩余部分不能被素数表[0]通过素数表[i-1]整除。如果primelist[i]^2>remaine,那么我们可以得出结论,remaine是primelist[i]和primelist[i]^2-1(包括)之间的某个素数,如果remaine=ab,那么a,b必须至少是primelist[i],所以remaine至少是primelist[i]^2,这是一个矛盾。因此,我们可以停止寻找素数


例如,如果速度更快,则取number=7。然后,当我们达到3(如3^2=9>7)时,条件被触发,因此我们不需要检查所有达到7的素数。

首先,它最好使用
remain

primelist[i] * primelist[i] > remain
这是一种优化,因为
reside
reside
的平方根之间不能有除数,因此您只剩下
reside
因子

此外,变量名
exponent
是谎言,它实际上包含指数加1。最好将其初始化为零,然后乘以指数+1