【问题标题】:Prime test, 2-digit numbersPrime 测试,2 位数字
【发布时间】:2011-05-01 12:02:54
【问题描述】:

我想打印所有 2 位长的素数。这是我的代码:

    for(int input = 11; input <= 99; input += 2){
        for(int x = 2; x < (int)Math.sqrt(input) + 1; x++){
            if(input%x != 0){
                System.out.println(input);
                break;
            }else{
                break;
            }
        }
    }

问题在于它会打印出像 35 或 49 这样不是素数的数字。

【问题讨论】:

  • 可能与您的问题无关,但是这两个break 语句似乎是多余的。
  • 这个调试起来很简单,为什么不用调试器呢?

标签: java loops primes


【解决方案1】:

您的素数测试不正确。一旦你找到一个不能被 input 整除的除数,你就停止测试一个数字 (input)。

这不是素数的定义 - 您需要测试 input 数字不能被小于它的 任何 除数整除 - 换句话说,您需要测试 x 的所有值在你可以将一个数字声明为素数之前。

input 可以被x 整除时,您可以跳出检查input % x != 0 的循环,但当它不能被x 整除时则不行 - 您需要继续检查该条件何时为真!

【讨论】:

  • “你需要测试输入的数字不能被任何小于它的除数整除”是不正确的,你不需要测试每个其他数字,只需它下面的所有其他素数
  • 你可以通过只测试你的号码的 sqrt 来节省更多的工作,因为任何需要一个小除数或最终高于你的号码:)
  • 嗯,是的,我们可以采取某些优化措施——我真的只是想解释素数的正确定义。
【解决方案2】:

我总是喜欢最短且最明显的答案就是硬编码输出的问题:

System.out.println("11\n13\n17\n19\n23\n29\n31\n37\n41\n43" +
   "\n47\n53\n59\n61\n67\n71\n73\n79\n83\n89\n97");

【讨论】:

  • 投反对票。这是作业,OP 需要掌握循环。提出的解决方案解决了问题,但错过了更大的意义。
  • @Seva:放轻松。当我发布这篇文章时,已经发布了 6 个很好的答案来帮助 OP 完成作业。我只是想说明如何很容易地针对一组特定的需求进行过度设计。顺便说一句,仅仅因为一些 SO 成员称之为作业,然后在没有得到 OP 确认的情况下将其标记为这样,并不意味着它是或应该被这样对待。
  • 确实,这针对OP特定问题的最佳解决方案。如果问题是打印素数直到出现内存不足错误,那将是不同的。 “不要比你需要的更复杂或浪费”也是非常重要的一课。
  • 如果真的是家庭作业,OP 就不会得到好成绩。他们在不同的班级学习了关于过度设计的危险的教训;我想这个是关于编码的基础知识。
【解决方案3】:

要找到一个素数,您不需要测试它下面的每个数字,直到它的平方根;你只需要测试它下面的所有其他素数。这是一个演示:

ArrayList<Integer> primes = new ArrayList<Integer>(); // hold every other prime numbers that we find
boolean isPrime;

// add first base prime number
primes.add(2);

for (int x = 3; x < max; x+=2) {  // start from 3 and skip multiples of 2
    isPrime = true;  // prove it's not prime
    for (Integer i : primes) {
        if (x % i == 0) {
            isPrime = false; // x is divisible by a prime number... 
            break; // exit loop, we proved it's not a prime
        }
    }
    if (isPrime) {
        if (x >= 10) {
            System.out.println(x);  // print only two digits prime numbers
        }
        primes.add(x);  // add x to our prime our number list for future checks
    }
}

** 编辑 **

静态方法中更灵活和可重用的实现(未针对列出大素数进行优化):

public static List<Integer> findPrimes(int min, int max) {
    LinkedList<Integer> primes = new LinkedList<Integer>();
    boolean isPrime;
    double square;

    // add first base prime number
    primes.add(2);

    for (int x = 3; x < max; x+=2) {  // start from 3 and skip multiples of 2

        isPrime = true;  // prove it's not prime
        square = Math.sqrt(x);
        for (Integer i : primes) {
            isPrime = x % i != 0;  // x is not prime if it is divisible by i
            if (!isPrime || i > square) { 
                break;
            }
        }
        if (isPrime) {
            primes.add(x);  // add x to our prime numbers
        }
    }

    // remove all numbers below min
    while (!primes.isEmpty() && primes.getFirst() < min) {
        primes.removeFirst();
    }

    return primes;
}

方法使用:

List<Integer> primes = findPrimes(10, 100);
System.out.println("Listing " + primes.size() + " prime numbers");
for (Integer prime : primes) {
    System.out.println(prime);
}

【讨论】:

    【解决方案4】:

    维基百科提供了一个很好的寻找素数的算法。它还列出了最多 100 个。

    如果您正在寻求调试帮助,我会单步调试您的代码,直到您看到哪些测试不正确。这是一个快速简单的程序,不会花很长时间。

    【讨论】:

      【解决方案5】:

      问题出在这块:

      if(input%x != 0)
      {
      System.out.println(input);
      break;
      }
      

      如果它不能被“x”的当前值整除,它将打印“输入”,但它可能被“x”的下一个值整除。在这种情况下,“输入”不是素数,而是打印出来的。

      正确代码:

      boolean flag;
      for(int input = 11; input <= 99; input += 2)
      {
              flag = true;
              for(int x = 2; x < (int)Math.sqrt(input) + 1; x++)
              {
                  if(input%x == 0)
                  {
                      flag = false;
                      break;
                  }
              }
              if(flag == true)
                  System.out.println(input);
      }
      

      【讨论】:

      • @ArtWorkAD:它给出了正确的结果。不打印非质数。请再次检查。
      【解决方案6】:

      这行得通。可以看到输出here

      public class Main {
      
      public static void main(String[] args) {
      for(int input = 11; input <= 99; input += 2){
          boolean found = false;
          for(int x = 2; x < (int)Math.sqrt(input) + 1; x++){
              if(input%x == 0){
                  found = true;
                  break;
              }
      
          }
          if(!found) {
                  System.out.println(input);
          }
      }
      }
      }
      

      【讨论】:

        【解决方案7】:

        您正在打印所有奇数。你总是跳出循环,所以x 永远不会超过 2。

        if(input%x != 0){
            System.out.println(input);
            break;  // <<-- break here
        }else{
            break;  // <<-- and break here
        }
        

        还要仔细考虑素数的定义:

        • 如果您测试的任何个数字是精确除数,则该数字不是素数。
        • 如果所有您测试的数字不是精确除数,则该数字是素数。

        只有在找到除数时才应该跳出循环。如果你还没有找到一个,你需要继续前进,直到你测试了所有的可能性。在你完成循环并知道结​​果之前,你不应该打印任何东西。

        【讨论】:

          【解决方案8】:
          for(int input = 11; input <= 99; input += 2){
              int found = 0;
              for(int x = 2; x < (int)Math.sqrt(input) + 1; x++)
                  if(input%x == 0){
                      found = 1;
                      break;
                  }
              if(found == 0)
                  System.out.println(input);
          
          }
          

          这应该做的工作

          【讨论】:

          • -1 这甚至不能编译。您不能使用 int 作为条件。即使它确实编译它也不会打印所需的输出。
          • 你确定它没有打印出想要的输出吗?我认为你的解决方案打印同样的东西......:/
          【解决方案9】:

          是的,因为它会打印出所有发现非因素的情况。 您只需要打印出无法找到因素的案例。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2012-06-16
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-07-19
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多