我已经开始学习用Java编写代码,并决定使用Project Euler网站为我提供一些小任务,以尝试并完成所学到的每一个新编码。所以我遇到了问题3:
13195的素数是5、7、13和29。600851475143的最大素数是多少?
我考虑了这个问题,研究了许多关于质数的理论,以及如何通过各种不同的计算找到质数的方法(以Eratosthenes筛为例),我想到的解决方案是测试2-> n的数,看看是否它们是质数,如果是,那么我将Tn变量(在这种情况下为600851475143)除以新发现的质数,看看它是否是一个因数。如果是这样,我将其分配给变量Hp(最高质数),并在程序结束时将Hp输出到控制台以给出结果。
这是我的代码:
public class Largest_Prime_Factor_NEW_SOLUTION { static long Tn = 600851475143L; static long Hp = 0; static boolean isPrime = false; public static void main(String[] args) { for (long i=2; i<Tn; i++) { System.out.println("TESTING NUMBER " + i); for (long k=2; k < i; k++) { if (i % k == 0) { System.out.println(i + " IS NOT A PRIME"); break; } else if (k + 1 == i) { isPrime = true; } } if (isPrime) { System.out.println(i + " IS A PRIME"); if (Tn % i == 0) { System.out.println(Tn + " IS DIVISIBLE BY " + i); Hp = i; } else { System.out.println(Tn + " IS NOT DIVISIBLE BY " + i); } } isPrime = false; } System.out.println("THE HIGHEST PRIME NUMBER OF " + Tn + " IS " + Hp); } }
现在我知道该代码效率很低,从一开始我就设法从我开始的地方压缩它(到处都是循环!),但是我要问的是,我该如何改进呢?它正在吞噬我,因为我研究的所有内容都与他人的所作所为相抵触,这非常令人困惑。我尝试了sieve方法,但我知道布尔数组只能是int数组,而不能是long数组?
我知道,在开始编码时,我将限于可以使用的知识,但是出于兴趣,我渴望看到最终的解决方案。
您可以做的是找到的最小除数Tn。假设是p,再次找到最低的除数Tn/p,依此类推。
Tn
p
Tn/p
现在,每一步p都是质素的[下面的解释]。因此,请收集它们,它们是的主要除数Tn。
为了提高时间复杂度,您最多可以检查除数(最多)ceil(sqrt(Tn)),而不是Tn-1。
ceil(sqrt(Tn))
Tn-1
当您开始检查的主要除数时Tn,您可以从开始2。一旦得到一个主要除数p,就不要从2for 重新开始Tn/p。因为,Tn/p同样的除数Tn,自Tn不必因数小于p,Tn/p不具备这一点。所以从头开始p[ p可以在Tn]中拥有多重力量。如果p不分开Tn,则移至p+1。
2
p+1
范例:
Tn = 45 1.从2开始。2不除以45。2 .下一个测试是针对3. 3被45整除。因此3是其主要除数。 3.现在从45/3 = 15检查素数除数,但从3开始,而不是从2开始。4.好吧,15可以被3整除。所以从15/3 = 5开始。5.注意,ceil(sqrt(5))是3。但是5不能被3整除,但是由于4> ceil(sqrt( 5)),我们可以毫无疑问地说5是素数。
因此45的素数除数是3和5。
为什么数字的最小除数(除1外)是质数?
假设以上陈述为假。那么数字N具有最小的复合除数,例如C。
因此,C | N现在C是合成的,因此除数小于其自身,但大于1。 假设C的这样的因数是P。 所以P | C,但我们有C | N => P | N,其中1 <P <C。
这与我们的假设相反,即C是N的最小除数,因此数的最小除数始终是质数。