【问题标题】:prime numbers switch in a java program has unexpected outputjava程序中的素数开关有意外的输出
【发布时间】:2014-09-26 21:41:20
【问题描述】:

我正在尝试创建一个程序,该程序读取 10 个整数的列表并询问用户是否想知道输入的整数是偶数/奇数、素数还是符号。 我看不出错误在哪里:

import java.io.*;
public class Menu1 {
public static void main(String args[])throws IOException{
    BufferedReader b=new BufferedReader(new InputStreamReader(System.in));
    int array[]=new int[10];
    int a=0, i=0;
    System.out.println("Welcome, please enter 10 integers:");
    try{
        for(i=0;i<10;i++){
            System.out.println("Enter integer "+(i+1)+":");
            array[i]=Integer.parseInt(b.readLine());
        }
    }catch(NumberFormatException e){
        System.err.println("Not an integer! "+e.getMessage());
    }           
    System.out.println("What would you like to know?\n(1) Even/Odd\n(2) Primes\n(3) Sign");
    try{
        a=Integer.parseInt(b.readLine());   
    }catch(NumberFormatException e){
        System.err.println("Not an integer! "+e.getMessage());
    }       
    switch (a){
    case 1:
        for(i=0;i<10;i++){
            if(array[i]%2==0)
                System.out.println(array[i]+" is even");
            else
                System.out.println(array[i]+" is odd");
        }
        break;
    case 2:
        for(int j=0;j<10;j++){
            for(i=2;i<array[j];i++){
                if(array[j]%i==0)
                    System.out.println(array[j]+" isn't prime");
                else
                    System.out.println(array[j]+" is prime");
            }
        }
        break;
    case 3:
        for(i=0;i<10;i++){
            if(array[i]>0)
                System.out.println(array[i]+" is positive");
            else if(array[i]<0)
                System.out.println(array[i]+" is negative");
            else
                System.out.println(array[i]+" has no sign");
        }
        break;
    default:
        System.out.println("Invalid Option");
    }
}

}

案例 1 和案例 3 工作正常,案例 2 是出现奇怪输出的地方;任何帮助将不胜感激

【问题讨论】:

  • 你得到什么样的“奇怪输出”?
  • 定义“奇怪的输出”
  • 打印前需要判断这个数是否为素数。现在,您检查的每个数字都将打印 N-2 次,其中 N 是数组中的值。当确定“不是素数”时,调整你的第二个 for 循环停止,然后只打印一次。
  • 这里是使用 eclipse luna 的输出:你想知道什么? (1) 偶数/奇数 (2) 素数 (3) 符号 2 5 是素数 5 是素数 5 是素数 7 是素数 7 是素数 7 是素数 7 是素数 7 是素数 9 是素数 9 不是素数

标签: java for-loop switch-statement


【解决方案1】:

在案例 2 的代码中:

case 2:
    for(int j=0;j<10;j++){
        for(i=2;i<array[j];i++){
            if(array[j]%i==0)
                System.out.println(array[j]+" isn't prime");
            else
                System.out.println(array[j]+" is prime");
        }
    }
    break;

您已经放置了一个System.out.println() 语句,它将在for 循环的每次迭代中执行。因此,如果您的数组中的给定元素array 是 5,您的代码将打印出您的数字是否可以被 2 到 5 之间的每个数字整除。这可能不是您想要的。

要解决这个问题,有几个选项:一个是,您可以设置一个布尔标志,当您发现该数字不是素数时设置该标志,然后检查该标志并在内部 for 循环之后打印您的结果:

case 2:
    for(int j=0;j<10;j++){
        boolean isPrime = true; // assume it's prime
        for(i=2;i<array[j];i++){
            if(array[j]%i==0)
                isPrime = false;
                break; // get out of the inner for loop early
        }
        if(isPrime)
            System.out.println(array[j]+" is prime");
        else
            System.out.println(array[j]+" isn't prime");
    }
    break;

【讨论】:

  • 最后的代码是错误的。它需要isPrime 默认为true,如果找到除数则设置为falseprintln 语句也被反转了。
  • 啊,你已经纠正了第一个问题。不过,println 语句仍然是错误的。
  • @chiastic-security 再次感谢您!
【解决方案2】:

这是一个检查数字是否为素数的函数:

public static boolean isPrimeNumber(int number) {
    if (number == 2 || number == 3) {
        return true;
    }
    if (number % 2 == 0) {
        return false;
    }
    int sqrt = (int) Math.sqrt(number) + 1;
    for (int i = 3; i < sqrt; i += 2) {
        if (number % i == 0) {
            return false;
        }
    }
    return true;
}

您可以为要检查的每个号码调用此函数。

你的 case2 会是这样的:

 case 2:
    for(int j=0;j<10;j++){    
            if(!isPrimeNumber(array[j]))
                System.out.println(array[j]+" isn't prime");
            else
                System.out.println(array[j]+" is prime");
    }
    break;

【讨论】:

    【解决方案3】:

    对于编程练习,给出的答案就可以了。如果这是一个真正的应用程序,使用非常大的数字,那么检查每个可能的除数的算法(甚至是对此的轻微改进)将会非常缓慢。

    虽然可以比这更有效地确定素数,但在实践中检查(非常)大的数字是否几乎是非常非常有效的 当然素数。这就是加密应用程序中使用的内容。

    更多详情,您可以查看Miller-Rabin

    如果您想要一个实现,您可以使用现成的,然后将您的号码转换为BigInteger,然后使用BigInteger.isProbablePrime(int certainty) 来确定它是否可能是素数。您可以使“可能”非常接近确定性,并且仍然非常有效。

    【讨论】:

      猜你喜欢
      • 2022-11-10
      • 2015-09-20
      • 1970-01-01
      • 1970-01-01
      • 2014-11-30
      • 1970-01-01
      • 2017-10-07
      • 2023-04-01
      相关资源
      最近更新 更多