我试图解决Project Euler的10个 th 问题,但由于某种原因,我无法做到正确。我是编程和Java的新手,所以我无法理解为什么它不起作用。问题的关键是要找到2,000,000以下所有素数的总和。
/* The sum of the primes below 10 is 2 + 3 + 5 + 7 = 17.
Find the sum of all the primes below two million.
*/
public static void main(String[] args){
long n = 1;
long sum = 0;
long limit;
System.out.println("Enter the limit of n: ");
limit = TextIO.getlnLong(); //TextIO is another input method
while (limit <= 0){
System.out.println("Enter the limit of n (must be positive): ");
limit = TextIO.getlnLong();
}
while (n < limit){
n++;
if (n % 2 != 0 && n % 3 != 0 && n % 5 != 0 && n % 7 != 0 && n != 1 || n == 2 || n == 3 || n == 5 || n == 7){ //this is my prime checking method, might be flawed
sum = sum + n;
System.out.println(+sum);
} //end if
}//end while
System.out.println("The sum of the primes below 2,000,000 is: " +sum);
} //end of main
答案 0 :(得分:4)
对于高效的素数检查方法,请阅读Sieve of Eratosthenes。
答案 1 :(得分:2)
你的主要方法被打破了。如果数字在2和数字的平方根之间没有任何除数,则数字为素数。 13 * 13会通过你的主要检查功能。
for i to sqrt(n):
if(n % i == 0):
OH NO NOT PRIME DO SOMETHING HERE?
if something is prime
add some stuff
答案 2 :(得分:1)
以下是2个比普通解决方案更好的解决方案:
1)迭代奇数(唯一偶数素数已经在总和中)并检查它们是否为素数:
private static boolean isOddPrime(int x) {
for ( int i = 3 ; i*i <= x ; i+=2 ){
if ( x % i == 0 ) {
return false;
}
}
return true;
}
private static void sumOfPrimes1(int n) {
long sum = 2;
for ( int i = 3 ; i < n ; i+=2 ) {
if ( isOddPrime(i) ) {
sum+=i;
}
}
System.out.println(sum);
}
2)使用 Eratosthenes筛选
private static void sumOfPrimes2(int n) {
boolean notPrimes[] = new boolean[n]; // default = false
for ( int i = 2 ; i*i < n ; i++ ) {
if ( !notPrimes[i] ) {
for ( int j = i*i ; j < n ; j+=i ){
notPrimes[j] = true;
}
}
}
long sum = 2 ;
for ( int i = 3 ; i < n ; i+=2 ) {
if ( !notPrimes[i] ) {
sum+=i;
}
}
System.out.println(sum);
}
我使用“notPrimes”(复合)代替“primes”作为数组,只是为了利用Java中的默认布尔值为false
这一事实。
<强>性能强>:
n | 2000000 8000000 16000000
------------+-------------------------------------------
Solution 1 | 1309 ms 8574 ms 22757 ms
Solution 2 | 119 ms 696 ms 1624 ms
答案 3 :(得分:0)
http://www.counton.org/explorer/primes/checking-if-a-number-is-prime/
检查数字N是一个质数的捷径是,我们不必尝试将每个数字从2依次转换为N(2、3、4、5、6…..N-1)来查看任何一个他们正好除以N。
exp:由于3是18的因数,并且18/3 = 6,则18 = 3x6。我们只需要测试较小的数字3,看它是否是18的因数而不是6。类似地,5是20的因数,而20 = 5x4,因此我们只需要测试较小的数字4。但是,如果我们不知道数字的因素怎么办?因此,测试一个数字是否为质数意味着我们只需要测试“较小”的因素。但是,较小的因素在哪里停止而较大的因素在哪里开始呢?这里的原理是: 假设一个数是N的因数,并且它小于数N的平方根。那么第二个因数必须大于平方根。 我们可以通过上面的示例看到这一点:对于18,我们只需要测试数字,直到18的平方根即4.243,即最多4!这比测试最多17个数字要快得多! 对于25,我们需要测试不超过25的平方根(即5)的数字。 对于37,我们只需要增加到6(因为6x6 = 36,所以37的平方根只会大一点)。
public static void main(String[] args) {
long sum = 0;
for (int i = 2; i < 2000000; i++) {
if (isPrime(i)) {
sum += i;
}
}
System.out.println(sum);
}
// check if a number is prime
private static boolean isPrime(int number) {
int sqrt = (int) Math.sqrt(number);
boolean isPrime = true;
// test up to square root of the number
for (int i = 2; i <= sqrt; i++) {
if (number % i == 0) {
isPrime = false;
break;
}
}
return isPrime;
}
答案 4 :(得分:-4)
public static void main(String args[])
{
long n = 1;
long sum = 0;
long limit=Integer.parseInt(args[0]);
while (n < limit)
{
n++;
if(n % 2 != 0 && n % 3 != 0 && n % 5 != 0 && n % 7 != 0 && n != 1 || n == 2 || n == 3 || n == 5 || n == 7)
{
sum = sum + n;
}
}
System.out.println("The sum of the prime numbers = " +sum);
}