我正在阅读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时,循环将结束?
答案 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
这是一种优化,因为remain
和remain
的平方根之间不存在除数,所以你只剩下因子remain
。
此外,变量名exponent
正在撒谎,它实际上包含指数加1。最好将其初始化为零并乘以exponent + 1
。