下一个Prime数字Java只能处理某些数字

时间:2014-02-27 23:15:43

标签: java primes

这个函数只适用于某些数字,但对于15或5,它不会给我正确的下一个素数。

public static int nextPrime(int n) {
    boolean isPrime = false;
    int m = (int) Math.ceil(Math.sqrt(n));
    int start = 3;
    if (n % 2 == 0) {
        n = n + 1;
    }
    while (!isPrime) {
        isPrime = true;
        for (int i = start; i <= m; i = i + 2) {
            if (n % i == 0) {
                isPrime = false;
                break;
            }
        }
        if (!isPrime) {
            n = n + 2;
        }
    }
    return n;
}

8 个答案:

答案 0 :(得分:1)

你不需要达到sqrt(n),你需要达到你正在评估的sqrt(数字)

例如,

考虑你传递n = 5

它将从3开始循环,它将在4结束循环,这不是你需要找到的下一个素数

外循环 从n + 1开始,直到找到素数 内循环 你应该从3和sqrt(numberUnderIteration)

开始

答案 1 :(得分:1)

您只是在原始数字的平方根处设置边界。为了检查每个下一个数字是否有效,您需要在n值更改时重新计算边界。所以,将int m = (int) Math.ceil(Math.sqrt(n));放在while循环中。

在开始任何计算之前,您还需要将n递增1,否则它将接受n本身作为素数(如果它是1)。例如,nextPrime(5)会返回5,因为它会传递条件。

最后,你不需要在while循环结束时将n增加2,因为如果你是偶数,它会爆发(继续将2加到偶数上甚至)。我已经评论了我改变的代码部分:

public static int nextPrime(int n) {
    boolean isPrime = false;

    int start = 2; // start at 2 and omit your if statement

    while (!isPrime) {
        // always incrememnt n at the beginning to check a new number
        n += 1;
        // redefine max boundary here
        int m = (int) Math.ceil(Math.sqrt(n));

        isPrime = true;
        // increment i by 1, not 2 (you're skipping numbers...)
        for (int i = start; i <= m; i++) {
            if (n % i == 0) {
                isPrime = false;
                break;
            } 
        }
        // you don't need your "if (!isPrime)..." because you always increment
    }
    return n;
}

public static void main(String[] args) {

    System.out.println(nextPrime(15)); // 17
    System.out.println(nextPrime(5)); // 7
    System.out.println(nextPrime(8)); // 11
}

答案 2 :(得分:0)

你需要在for循环中计算m。

  while (!isPrime) {
     isPrime = true;
      int m = (int) Math.ceil(Math.sqrt(n));

     // do other stuff

答案 3 :(得分:0)

您的代码工作正常,除非将素数作为输入给出,您的方法本身会返回输入。

如果5是您的输入nextPrime(5),则返回5。如果你想在这种情况下返回7(5之后的下一个素数)。

只需在方法开头添加n=n+1;即可。希望这有帮助

答案 4 :(得分:0)

为了好玩,我编写了一个跟踪已知质数的快速Prime类,为查找多个大质数提供了巨大的性能提升。

import java.util.ArrayList;

public class Primes {

    private static ArrayList<Integer> primes = new ArrayList<Integer>();

    public static int nextPrime(int number){

        //start it off with the basic primes
        if(primes.size() == 0){
            primes.add(2);
            primes.add(3);
            primes.add(5);
            primes.add(7);
        }

        int idx = primes.size()-1;
        int last = primes.get(idx);

        //check if we already have the prime we are looking for
        if(last > number){
            //go to the correct prime and return it
            boolean high = false;
            boolean low = false;
            int prevIdx = 0;
            int spread = 0;
            //keep finagling the index until we're not high or low
            while((high = primes.get(idx-1) > number) || (low = primes.get(idx) <= number)){
                spread = Math.abs(prevIdx-idx);
                //because we always need to move by at least 1 or we will get stuck
                spread = spread < 2 ? 2: spread;
                prevIdx = idx;
                if(high){
                    idx -= spread/2;
                } else if(low){
                    idx += spread/2;
                }
            };
            return primes.get(idx);
        }

        /*FIND OUR NEXT SERIES OF PRIMES*/

        //just in case 'number' was prime
        number++;

        int newPrime = last;
        //just keep adding primes until we find the right one
        while((last = primes.get(primes.size()-1)) < number){
            //here we find the next number
            newPrime += 2;
            //start with the assumption that we have a prime, then try to disprove that
            boolean isPrime = true;
            idx = 0;
            int comparisonPrime;
            int sqrt = (int) Math.sqrt(newPrime);
            //make sure we haven't gone over the square root limit- also use post-increment so that we use the idx 0
            while((comparisonPrime = primes.get(idx++)) <= sqrt){
                if(newPrime % comparisonPrime == 0){
                    isPrime = false;
                }
            }
            if(isPrime){
                primes.add(newPrime);
            }
        }

        return last;
    }
}

这是测试:

public class Test {

    public static void main(String[] args){

        long start;
        long end;
        int prime;
        int number;

        number = 1000000;
        start = System.currentTimeMillis();
        prime = Primes.nextPrime(number);
        end = System.currentTimeMillis();
        System.out.println("Prime after "+number+" is "+prime+". Took "+(end-start)+" milliseconds.");

        number = 500;
        start = System.currentTimeMillis();
        prime = Primes.nextPrime(number);
        end = System.currentTimeMillis();
        System.out.println("Prime after "+number+" is "+prime+". Took "+(end-start)+" milliseconds.");  

        number = 1100000;
        start = System.currentTimeMillis();
        prime = Primes.nextPrime(number);
        end = System.currentTimeMillis();
        System.out.println("Prime after "+number+" is "+prime+". Took "+(end-start)+" milliseconds.");      
    }
}

这导致以下输出:

Prime after 1000000 is 1000003. Took 384 milliseconds.
Prime after 500 is 503. Took 10 milliseconds.
Prime after 1100000 is 1100009. Took 65 milliseconds.

正如您所看到的,第一次迭代需要很长时间,但我们只需要执行一次该操作。在那之后,我们的时间减少到几乎没有质量小于我们的第一个数字(因为它只是一个查找),并且对于比我们的第一个更大的素数非常快(因为我们已经做了大多数的工作)。

编辑:使用Binary Search Algorithm的变体更新了对现有素数的搜索。它将搜索时间缩短了至少一半。

答案 5 :(得分:0)

import java.util.Scanner;

class Testing 
{
    public static void main(String Ar[])
    {
        int a = 0, i, j;
        Scanner in = new Scanner(System.in);
        a = in.nextInt();
        for (j = a + 1;; j++) 
        {
            for (i = 2; i < j; i++) 
            {
                if (j % i == 0)
                break;
            }
              if (i == j) 
             {
                 System.out.println(j);
                 break;
             }
        }
    }
}

答案 6 :(得分:0)

这是查找给定数字的下一个素数的完美代码。

public class NextPrime
{

    int nextPrime(int x)
    {
        int num=x,j;
            for( j=num+1;;j++)
            {
                int count=0;

                    for(int i=1;i<=j;i++)
                    {
                        if(j%i==0)
                        {
                        count++;
                        //System.out.println("entered");
                        }
                        //System.out.println(count);
                    }
                    if(count==2)
                    {
                    System.out.println(" next prime is ");
                    break;
                    }

            }return j;
    }

    public static void main(String args[])
    {
        NextPrime np = new NextPrime();
        int nxtprm = np.nextPrime(9);
        System.out.println(nxtprm);
    }

}

答案 7 :(得分:0)

//I hope the following code works exactly.


import java.util.Scanner;
public class NextPrime {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("Enter a positive integer number : ");
        int n = scanner.nextInt();
        for (int x = n + 1;; x++) {
            boolean isPrime = true;
            for (int i = 2; i < x / 2; i++) {
                if (x % i == 0) {
                    isPrime = false;
                    break;
                }
            }
            if (isPrime) {
                System.out.println("Next prime is : " + x);
                break;
            }
        }
    }
}