我做了一个代码,可以测试一个数字是否是素数、sophie-germain素数、双素数和/或mersenne素数。我需要把它变成一个新的代码,测试0-1000000的所有数字,并打印出属于这些类型的每个数字。这是我需要更改的原始程序
import java.util.Scanner;
public class PrimeMethodsDemo_slm {
public static boolean isPrime (int n) {
boolean isPrime = true;
if (n < 2) isPrime = false;
else if (n == 2) isPrime = true;
else for (int i = 2; i < Math.sqrt(n) + 1; ++i) {
if (n % i == 0) return false;
}
return isPrime;
}
public static boolean isSophieGermainPrime (int n) {
boolean isPrime = true;
if (n < 2) isPrime = false;
else if (n == 2) isPrime = true;
else for (int i = 2; i < Math.sqrt(n) + 1 & (i < Math.sqrt(n * 2 + 1) + 1);
++i)
{
if (n % i == 0) return false;
}
return isPrime;
}
public static boolean isTwinPrime (int n) {
boolean isPrime = true;
if (n < 2) isPrime = false;
else if (n == 2) isPrime = true;
else for (int i = 2; i < Math.sqrt(n) & i < Math.sqrt(n + 2) + 1; ++i) {
if (n % i == 0) return false;
}
return isPrime;
}
public static boolean isMersennePrime (int n) {
boolean isPrime = true;
if (n < 2) isPrime = false;
else if (n == 2) isPrime = true;
else
for (int i = 2; i < Math.sqrt(n) + 1 & i < Math.sqrt(2 * n - 1) + 1; ++i)
{
if (n % i == 0) return false;
}
return isPrime;
}
}
我将从简化isPrime(int n)
方法开始。以下是我的简化解决方案:
public static boolean isPrime (int n) {
if (n < 2) return false;
BigInteger bigInt = BigInteger.valueOf(n);
return bigInt.isProbablePrime(100);
}
据我所知,如果数字一开始就是素数,那么其余的方法根据定义都是正确的。因此,这些方法中的每一个都必须检查给定的数字n
是否是素数。如果给定的数字不是素数,那么您希望早点返回。否则,您需要继续计算,看看给定的数字是Sophie Germain、Twin还是Mersenne素数。因此,在继续计算之前,这些方法中的每一个都应该调用isPrime(int n)
。例如,
public static boolean isSophieGermainPrime (int n) {
return isPrime(n) && isPrime(2*n + 1);
}
public static boolean isTwinPrime (int n) {
return isPrime(n) && (isPrime(n + 2) || isPrime(n - 2));
}
最后,您需要包含一个main
方法,该方法迭代范围内的所有数字,并打印出一个数字是素数、Sophie Germain、Twin和/或Mersenne素数。
public static void main (String[] args) {
System.out.printf("%15s | %6s | %16s | %5s | %9s |%n", "Number", "Prime?", "Sophie Germain?", "Twin?", "Mersenne?");
for (int i = 1; i <= 1000000; i++) {
System.out.printf("%15d | %6b | %16b | %5b | %9b |%n", i, isPrime(i), isSophieGermainPrime(i), isTwinPrime(i), isMersennePrime(i));
}
}
显然,在这里,向控制台输出一百万行可能不是正确的做法。相反,我建议使用文件编写器并将每一行输出到一个文件(除非特定要求是转储到控制台(。问题是,除非您更改控制台使用的缓冲区的大小,否则将丢失大量输出。
如果您决定使用我的main
方法,输出将如下所示(Mersenne的布尔值可能不正确(:
Number | Prime? | Sophie Germain? | Twin? | Mersenne? |
1 | false | false | false | false |
2 | true | true | false | true |
3 | true | true | true | true |
4 | false | false | false | false |
5 | true | true | true | true |
6 | false | false | false | false |
7 | true | false | true | true |
8 | false | false | false | false |
9 | false | false | false | false |
10 | false | false | false | false |
11 | true | true | true | false |
12 | false | false | false | false |
13 | true | false | true | true |
14 | false | false | false | false |
15 | false | false | false | false |
16 | false | false | false | false |
17 | true | false | true | true |
18 | false | false | false | false |
19 | true | false | true | true |
20 | false | false | false | false |
21 | false | false | false | false |
22 | false | false | false | false |
23 | true | true | false | false |
24 | false | false | false | false |
25 | false | false | false | false |
26 | false | false | false | false |
27 | false | false | false | false |
28 | false | false | false | false |
29 | true | true | true | false |
30 | false | false | false | false |
31 | true | false | true | false |
更新:OP评论道:;主方法有效,但我只需要它打印出每种类型的素数">
使用我的解决方案并遵守此要求的一种潜在方法是简单地指示循环打印您想要的内容。例如,要打印Sophie Germain素数,只需执行以下操作:
public static void main (String[] args) {
System.out.printf("%10s%n", "Sophie Germain Primes");
for (int i = 1; i <= 1000000; i++) {
if (isSophieGermainPrime(i)) {
System.out.printf("%7d%n", i);
}
}
}
这将输出类似的内容
Sophie Germain Primes
2
3
5
11
23
29
41
53
83
89
113
131
...
根据Wolfram MathWorld网站,上面显示的顺序是正确的