当我从梁的Java编程书的介绍中学习时,我陷入了困境。问题是要有效地找到素数。
为了找出n是否为素数,我们必须检查n是否可被数字2,3,4,...,sqrt(n)整除。
我们可以通过检查n是否可以被数字2,3,4,...,floor(sqrt(n))整除来使这个算法更有效。
例如,36到48之间的数字,它们的(int)(Math.sqrt(数字))是6.但是,根据以下程序,对于数字= 40,squareRoot是7,而不是6.即,< strong>根据数学证明,我们检查40是否是素数,通过检查40可以被2,3,4,5,6整除。 根据下面的程序,我们检查40是否是素数,通过检查40可以被2,3,4,5,6,7整除。这个矛盾。我不明白。请帮忙。
以下是实现此问题的算法:
import java.util.Scanner;
public class EfficientPrimeNumbers {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("Find all prime numbers <= n, enter n: ");
int n = input.nextInt();
// A list to hold prime numbers
java.util.List<Integer> list =
new java.util.ArrayList<Integer>();
final int NUMBER_PER_LINE = 10; // Display 10 per line
int count = 0; // Count the number of prime numbers
int number = 2; // A number to be tested for primeness
int squareRoot = 1; // Check whether number <= squareRoot
System.out.println("The prime numbers are \n");
// Repeatedly find prime numbers
while (number <= n) {
// Assume the number is prime
boolean isPrime = true; // Is the current number prime?
if (squareRoot * squareRoot < number) squareRoot++;
// For numbers between 36 and 48, squareRoot is 7 which contradicts with the matematical proof.!!!
// ClosestPair if number is prime
for (int k = 0; k < list.size()
&& list.get(k) <= squareRoot; k++) {
if (number % list.get(k) == 0) { // If true, not prime
isPrime = false; // Set isPrime to false
break; // Exit the for loop
}
}
// Print the prime number and increase the count
if (isPrime) {
count++; // Increase the count
list.add(number); // Add a new prime to the list
if (count % NUMBER_PER_LINE == 0) {
// Print the number and advance to the new line
System.out.println(number);
}
else
System.out.print(number + " ");
}
// Check if the next number is prime
number++;
}
System.out.println("\n" + count +
" prime(s) less than or equal to " + n);
}
}
答案 0 :(得分:0)
该程序仅通过素数检查可分性低于或等于sqrt(number) + 1
。检测到素数后,它会添加到您的list
对象中:
if (isPrime) {
count++; // Increase the count
list.add(number); // Add a new prime to the list
您可以在此处按照此列表中的数字检查可分性:
for (int k = 0; k < list.size() && list.get(k) <= squareRoot; k++) {
if (number % list.get(k) == 0) { // If true, not prime
因此,对于36
和48
之间的数字,它会检查2, 3, 5, 7
,这实际上比2, 3, 4, 5, 6
更好。渐渐地,它们仍然是相同的,但在实践中,你通过仅检查对素数的可分性来节省一些工作。
实际上,由于您描述的原因,您可以保存操作并将<=
中的list.get(k) <= squareRoot
更改为<
。然后,对于7
和36
之间的数字,它甚至不会对48
感到烦恼,而且它将更接近您所拥有的理论。