Java 数组保存素数并用它来寻找下一个素数
Java Array saving prime numbers and using it to find next prime
我在理解老师要我做什么时遇到了一个小问题。我所做的是一个代码,可以将所有素数保存在一个可以显示的数组中。但现在他要我 "optimize" 代码,据我所知,尝试将一个数除以质数。例如:如果我有 2、3、5,下一个素数就是不能除以其中任何一个的数。所以我不必尝试 2、3、4、5,而只需尝试 2、3、5(数组中的数字)。例如: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]);
}
}
}
目前检查数字是否为质数的代码是:
for (numberDividing = 2; (numberDividing < divider) && (divider % numberDividing != 0); numberDividing++) {
}
if (numberDividing >= divider) {
arrayPrime[x] = divider;
x++;
}
所以它正在检查从 2 到最后一个素数的所有数字。但它没有必要这样做:它只需要检查数组中已有的素数。
为了使您的代码更具可读性,我建议将您的检查移至单独的私有方法。我还将 x
重命名为 primeCount
:
private boolean isPrime(int number) {
for (int i = 0; i < primeCount; i++) {
if (number % arrayPrime[i] == 0)
return false;
}
return true;
}
那么你的调用代码就变成了:
for (int divider = 2; divider <= number; divider++) {
if (isPrime(divider))
arrayPrime[primeCount++] = divider;
}
您还可以进行另一个相当简单的优化。您不需要检查任何大于测试数平方根的素数,因为此时您已经检查了更小的因子:
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;
}
如果您不想使用单独的方法,则:
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;
}
并且,为了您以后的学习,这里有一种使用质数生成器实现相同结果的更优雅的方法:
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;
}
}
你是对的,你只需要将新数字除以以前发现的素数。我在下面所做的只是循环遍历所有发现的素数,并使用布尔值来跟踪每个数字是否为素数。我还使用 ArrayList 而不是数组,这样就不会像原始数组中那样有很多未使用的块。希望这可以帮助!
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);
我在理解老师要我做什么时遇到了一个小问题。我所做的是一个代码,可以将所有素数保存在一个可以显示的数组中。但现在他要我 "optimize" 代码,据我所知,尝试将一个数除以质数。例如:如果我有 2、3、5,下一个素数就是不能除以其中任何一个的数。所以我不必尝试 2、3、4、5,而只需尝试 2、3、5(数组中的数字)。例如: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]);
}
}
}
目前检查数字是否为质数的代码是:
for (numberDividing = 2; (numberDividing < divider) && (divider % numberDividing != 0); numberDividing++) {
}
if (numberDividing >= divider) {
arrayPrime[x] = divider;
x++;
}
所以它正在检查从 2 到最后一个素数的所有数字。但它没有必要这样做:它只需要检查数组中已有的素数。
为了使您的代码更具可读性,我建议将您的检查移至单独的私有方法。我还将 x
重命名为 primeCount
:
private boolean isPrime(int number) {
for (int i = 0; i < primeCount; i++) {
if (number % arrayPrime[i] == 0)
return false;
}
return true;
}
那么你的调用代码就变成了:
for (int divider = 2; divider <= number; divider++) {
if (isPrime(divider))
arrayPrime[primeCount++] = divider;
}
您还可以进行另一个相当简单的优化。您不需要检查任何大于测试数平方根的素数,因为此时您已经检查了更小的因子:
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;
}
如果您不想使用单独的方法,则:
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;
}
并且,为了您以后的学习,这里有一种使用质数生成器实现相同结果的更优雅的方法:
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;
}
}
你是对的,你只需要将新数字除以以前发现的素数。我在下面所做的只是循环遍历所有发现的素数,并使用布尔值来跟踪每个数字是否为素数。我还使用 ArrayList 而不是数组,这样就不会像原始数组中那样有很多未使用的块。希望这可以帮助!
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);