繁体   English   中英

为什么此质检程序起作用,而如果我尝试使其更高效则不起作用

[英]Why does this prime checker work, and not work if I try to make it more efficient

下面是我用Java编写的第一个程序(在Internet的帮助下)。 它是一个程序,用于检查给定的整数是否为质数,并提示用户反馈。 如果用户输入的不是整数,则输出的不是整数。 输入大整数时也会发生后者。 这是代码:

import java.util.Scanner;

class BasicPrime1 {
    public static void main(String[] args) {

        try {
            System.out.println("Enter an Integer: ");
            Scanner sc = new Scanner(System.in);

            int i; 
            int number = Integer.parseInt(sc.nextLine());

        // 1 and numbers smaller than 1 are not prime
            for (i = 1; number <= i;) {
                System.out.println("NOT a prime!");
                break;
            }

        // Number is not prime if the remainder of a division (modulus) is 0
            for (i = 2; i < number; i++) {  
                int n = number % i;         
                if (n == 0) {                 
                    System.out.println("NOT a prime!");
                    break;
                }  
            }

        // I do not understand why the if-statement below works.
            if(i == number) { 
                System.out.println("YES! PRIME!");
            }
        }

        catch(NumberFormatException nfe) {
            System.out.println("Not an integer!");
        }

    }
}

该程序可以完成他的工作,但是我不知道为什么带有if语句的部分起作用。 “ i ==数字”的值如何可能为true (输入质数时会打印出“ YES!PRIME”)? 局部变量i在for循环中递增,但是if语句在for循环之外。

/编辑 ,正如吉姆·刘易斯Jim Lewis)指出的那样,下面的段落是胡说八道
现在考虑一下,我能想到的唯一原因是因为==运算符检查i-'object'和number-'object'是否属于相同的'type'(即具有引用)到同一对象)。 由于它们都属于原始整数的类型,因此该程序将捕获整数(其他输入将引发NumberFormatException,该数字将被捕获并输出“非整数”)。 质数的那些传递第一个for循环,然后神奇的if语句给出“ true”,并输出“ YES!PRIME!”。

我在正确的轨道上吗?

我通过删除神奇的if语句并将其更改为if-else语句,从而改进了该程序:( / edit 修复了代码问题,感谢ajb

boolean factorFound = false;            
for (i = 2; i < Math.sqrt(number) + 1; i++) {
    int n = number % i;
    if (n == 0) {
        factorFound = false;
        break;
    }  
    else {
        factorFound = true; 
    }
}
if(factorFound == false) System.out.println("NOT a prime!");
if(factorFound == true) System.out.println("YES! PRIME!");

通过仅增加到输入数字的平方根,计算时间得到了改善(我知道,仅检查奇数或使用AKS Primality Test甚至可以进一步改善计算时间,但这并不重要)。

我的主要问题是为什么我不能以相同的方式提高第一个程序的效率(使用神奇的if语句)。 当我在第一个程序中像这样的for循环增强“(i = 2; i <Math.sqrt(number)+ 1; i ++)”时,它不再打印“ YES!PRIME!”。 输入素数时。 它给出了一个空白。 即使我先前的解释是正确的-可能不是-也没有解释。

您可以启发我。

解答: int i在for循环范围之外,并且经过多次for循环直至达到数值,当我们确定它是质数时,i的值将达到数值number 此外,在检查消失的“是!头等!”之后 语句再次证明实际上可以将if语句和for循环中的数字都更改为(Math.sqrt(number)+ 1)并具有有效的代码。 因此,问题是基于错误的前提。

ifor循环之外声明,所以它的值仍然在范围内,并且在循环结束后才可用(与比较数据类型或类似内容无关!)。

如果未找到除数,则i < number循环条件最终将失败,且i == number (如果循环找到除数并命中break语句,则该条件不再成立)。

当您执行sqrt优化时,循环的结束条件将发生更改,因此即使循环数是质i == numberi == number在循环退出后也不再成立。

在我看来,更明确地明确设置一个标志(例如,在退出循环之前isPrime=0 ),然后检查该标志,而不是查看循环变量以查看循环是否完成。

//我不明白下面的if语句为什么起作用

说明:因为我一直递增,直到等于数字。 如果在sqrt(number)停止,则if语句将始终失败。

顺便说一句,我不喜欢使用整数的平方根。 我更喜欢使用isPrime函数:

        if (number < 2) return false;
        if (number > 2 && number % 2 == 0) return false;
        for (int i = 3; i * i <= number; i = i + 2)
            if (number % i == 0) return false;
        return true;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM