【问题标题】:Code that prints all Prime, Sophie Germain Prime, Twin Prime and Mersenne Prime numbers 1 to 1000000打印所有 Prime、Sophie Germain Prime、Twin Prime 和 Mersenne Prime 数字 1 到 1000000 的代码
【发布时间】:2021-07-19 07:57:07
【问题描述】:

我编写了一个代码,可以测试一个数是否是素数、索菲热尔曼素数、孪生素数和梅森素数。我需要把它变成一个新代码来测试所有数字 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;
    }
}

【问题讨论】:

  • 您的代码缺少main 方法。如果您的原始代码中有它,请添加它。
  • 另外,编辑代码以显示原始方法。我根据误解的要求进行了错误的编辑。

标签: methods boolean


【解决方案1】:

我将从简化 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 和/或梅森素数。

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 方法,输出将如下所示(显示的梅森布尔值可能不正确):

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 website是正确的

【讨论】:

  • 我还没有测试你给我的布尔方法的简化版本,主要方法有效,但我只需要它打印出每种类型的素数,我目前正在尝试弄清楚如何做到这一点。感谢您的帮助,非常感谢。
  • @seb93 原理是一样的。您想创建一个基本案例方法来检查给定数字是否为素数。那么,您想使用该方法来推导它是否也是那些特殊情况之一。例如,如果 p2p+1 都是素数,则称素数 p 是 Sophie Germain 素数。因此,我的确定方法是isSophieGermain(int n) { return isPrime(n) && isPrime(2*n = 1);}` 你看到了吗?您可以在确定是否打印数字的方法中使用这些方法。例如:if (isSophieGermain(n)) {System.out.print(n);}
  • @seb93 我上面显示的表格不适用于梅森素数,因为它将根据指数n 而不是实际的梅森素数打印truefalse。这是因为我使用的是Math.pow(2, n) - 1,并且循环基于n 打印出来。你也必须弄清楚这一点。
猜你喜欢
  • 1970-01-01
  • 2019-04-08
  • 1970-01-01
  • 2011-05-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-23
  • 2013-05-19
相关资源
最近更新 更多