简体   繁体   中英

Finding the 10001:st prime number (Euler project)

I am doing challenge 7 on the Euler project, which requires me to find the 10001:st prime number.

My attempt is as follows:

    int i=2; //the number to check if prime
    int c=0; //the amount of prime numbers

    while(true){

        //checks if i%n == 0, if so, i is not a prime number. 
        for(int n=2;n<=prob.getMax(i);n++){
            //it is not a prime number
            if(i%n==0){
                break;
            }

            //it is a prime number 
            if(n==prob.getMax(i)){
                c++;
                break;
            }

        }
        i++;

        //if c == 10001 we have found the 10001:st prime number
        if(c==10001){
            System.out.println(i);
            break;
        }

    }

}

public int getMax(int x){

    return (int) Math.ceil(Math.sqrt(x));

}

I am returned the value 104760 but that does not seem to be correct. I cannot understand what I am doing wrong, since I seem to get a reasonable value. Could anyone point me in the right direction?

And also: is there any better way to compute these kind of problems? I seem to be using a for-loop and brute forcing my way to the solution on every problem.

You increase i before checking whether the found prime is the 10001st one. By swapping the order of these actions, it should work.

You are increasing i (with i++ ) before showing the result. The 100001 prime may be 104760-1.

One advise, try to avoid those while(true). You can do something like:

c = 0;
while (c < 10001) {
    ....
    c++
}

In your code, you are not checking the prob.getMax(i) which is in for loop. Add another check in the body of your for loop, something like the following:

if(n==theDesiredNumber){
 //...
 break;
}

By searching you can find out that the 10001st prime number is 104743. I changed your algorithm to :

public static void main(String... args) {
  int i = 2; //the number to check if prime
  int c = 1; //the counter for prime numbers have found so far

    while (true) {

       if(isPrime(i)){
           c++;
       }

        //if c == 10001 we have found the 10001:st prime number
        if (c == 10001) {
            System.out.println(i);
            break;
        }
        i++;

    }

}

public static boolean isPrime(int number) {
    for (int i = 2; i <= getMax(number); i++) {
        if (number % i == 0)
            return false;
    }
    return true;
}

public static int getMax(int x) {

    return (int) Math.ceil(Math.sqrt(x));

}

One thing to note for prime numbers is that with the exception of the number 2, they are always odd numbers and you don't have to check if the number is divisible by every number before it.

public class StackOverflow {
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // Starting at 1 cause I'm already including 2
        long primeCount = 1; 

        // Start with an odd number cause primes are never even
        long prime = 1;

        Calendar start = Calendar.getInstance();
        while (primeCount < 10001) {
            prime += 2;
            if (isPrime(prime)) {
                primeCount++;
            }
        }

        System.out.println(prime);
        System.out.println(String.format("Elapsed Time: %d ms", Calendar.getInstance().getTimeInMillis() - start.getTimeInMillis()));
    }

    private static boolean isPrime(long prime) {
        if (prime <= 1)
            return false;
        else if (prime % 2 == 0)
            return (prime == 2);
        else
        {
            int divisor = 3;
            double upperLimit = Math.sqrt((double)prime) + 1;

            while (divisor <= upperLimit)
            {
                if (prime % divisor == 0)
                    return false;

                // Skip by two cause an odd number is never evenly divisible by an even number
                divisor +=2;
            }
            return true;
        }
    }
}

Result (!!!!SPOILER ALERT!!!!!)

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM