简体   繁体   English

Java数组保存质数并使用它查找下一个质数

[英]Java Array saving prime numbers and using it to find next prime

I have a small problem understanding what my teacher wants me to do. 我在理解老师要我做什么方面有一个小问题。 What I have made is a code that saves me all the Prime numbers in an Array that can be displayed. 我编写的代码可以将所有素数保存在可以显示的数组中。 But now he wants me to "optimize" the code with, as far as I understand, try to divide a number only by the numbers that are prime. 但是现在,他要我据我所知用“优化”代码,尝试仅将数字除以质数。 For example : if I have 2,3,5 the next number to be prime is the number that doesn't divide by any of this. 例如:如果我有2,3,5,则下一个要素数的数字是不除以任何一个的数字。 So I don't have to try 2,3,4,5 but only 2,3,5 (the numbers that I have in the array). 因此,我不必尝试2,3,4,5,而只需尝试2,3,5(数组中的数字)。 And for example : 2,3,4,5,7 are primes, 10 is not because it divides by 2 then it has to jump on the next number. 例如:2,3,4,5,7是质数,10不是因为它除以2,所以必须跳到下一个数字。

public static void main(String[] args) {
    String introducedNumber = JOptionPane.showInputDialog("Introduce a number"); //with JOptionPane imported will ask you a small box for a number
    int number, divider, numberDividing; //declaring the int's

    number = Integer.parseInt(introducedNumber); //converting the input to a int
    int x = 0; //starting X to 0 since its 1st array position
    int[] arrayPrime = new int[number]; //declaring and creating an array
    for (divider = 1; divider <= number; divider++) { //for to run till numbers
        //for that checks if the number divides by any other than himself
        for (numberDividing = 2; (numberDividing < divider) && (divider % numberDividing != 0); numberDividing++) {
        }

        if (numberDividing >= divider) {
            arrayPrime[x] = divider;
            x++;
        }
    }
    for (int i = 0; i < x; i++) {
        System.out.println(arrayPrime[i]);
    }

}

} }

At the moment your code to check whether a number is prime is: 目前,您检查数字是否为质数的代码是:

    for (numberDividing = 2; (numberDividing < divider) && (divider % numberDividing != 0); numberDividing++) {
    }

    if (numberDividing >= divider) {
        arrayPrime[x] = divider;
        x++;
    }

So it is checking all numbers from 2 to the last prime. 因此它正在检查从2到最后一个质数的所有数字。 But there's no need for it to do that: it only needs to check the primes you already have in your array. 但是不需要这样做:它只需要检查数组中已经存在的素数即可。

To make your code a bit more readable, I suggest moving your check to a separate private method. 为了使您的代码更具可读性,建议将支票移到单独的私有方法中。 I've also renamed x to primeCount : 我也将x重命名为primeCount

private boolean isPrime(int number) {
    for (int i = 0; i < primeCount; i++) {
        if (number % arrayPrime[i] == 0)
            return false;
    }
    return true;
}

Then your calling code becomes: 然后,您的调用代码将变为:

for (int divider = 2; divider <= number; divider++) {
    if (isPrime(divider))
        arrayPrime[primeCount++] = divider;
}

There is another fairly trivial optimisation you can do. 您可以执行另一项相当简单的优化。 You don't need to check any primes that are greater than the square root of the test number because you've already checked smaller factors at that point: 您不需要检查任何大于测试号平方根的素数,因为此时您已经检查了较小的因数:

private boolean isPrime(int number) {
    for (int i = 0; i < primeCount; i++) {
        int prime = arrayPrime[i];
        if (prime * prime > number)
            break;
        else if (number % prime == 0)
            return false;
    }
    return true;
}

If you don't want to use a separate method, then: 如果您不想使用单独的方法,则:

for (int divider = 2; divider <= number; divider++) {
    boolean isPrime = true;
    for (int i = 0; i < primeCount && isPrime; i++) {
        isPrime = number % arrayPrime[i] > 0;
    }
    if (isPrime)
        arrayPrime[primeCount++] = divider;
}

And, for your future study, here's a more elegant way to achieve the same result using a prime number generator: 而且,在以后的学习中,这是一种使用质数生成器达到相同结果的更优雅的方法:

public class PrimeGenerator {
    private long current = 1;
    private final List<Long> primes = new ArrayList<>();

    public long next() {
        do {
            current++;
        } while (primes.stream().anyMatch(n -> current % n == 0));
        primes.add(current);
        return current;
    }
}

You were right that you only need to divide new numbers by previously discover primes. 没错,您只需要将新数字除以先前发现的质数即可。 What I do below is simply loop through all the discovered primes and use a boolean to keep track of if each number is prime. 我在下面所做的只是简单地遍历所有发现的素数,并使用布尔值来跟踪每个数字是否为素数。 I also use an ArrayList instead of an array so that there are not numerous unused blocks like in your original array. 我还使用ArrayList而不是数组,这样就不会有很多未使用的块,如原始数组中那样。 Hope this helps! 希望这可以帮助!

ArrayList<Integer> arrayPrime = new ArrayList<Integer>(); //use array list instead of static array
arrayPrime.add(2); //seed first prime number
boolean isPrime; //boolean to determine if prime

for (divider = 3; divider <= number; divider++) { //loop up to input number, starting at 3

    isPrime = true; //initialize true for each new number

    for (i = 0; i < arrayPrime.size(); i++) { //loop through each previous prime

        if (divider % arrayPrime[i] == 0) { //see if number is divisible by previous prime
            isPrime = false;
            break; //break out of loop
        }
    }

    if(isPrime){ //if it did not divide evenly, it is prime
        ArrayPrime.add(divider);
    }
}

System.out.println(list);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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