java - 为什么这个主要检查器可以工作,但如果我试图提高它的效率却不起作用

标签 java primes math.sqrt

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

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 == number”怎么可能给出 true 值(当您输入素数时,它会打印出“YES!PRIME”)?局部变量 i 在 for 循环中递增,但 if 语句位于 for 循环之外。

/edit下面的段落是胡说八道,如 Jim Lewis points out
现在想想,我能想到这种情况的唯一原因是因为 == 运算符检查 i-'object' 和 number-'object' 是否属于同一“类型”(即,具有对同一对象的引用)。由于它们都属于原始整数类型,因此该程序捕获整数(其他输入抛出 NumberFormatException,该异常被捕获并输出“不是整数”)。质数通过第一个 for 循环,然后神奇的 if 语句给出“true”并打印出“YES!PRIME!”。

我走在正确的道路上吗?

我通过删除神奇的 if 语句并将其更改为如下 if-else 语句来改进了该程序:(/edit 修复了问题代码感谢 answer of 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 语句)的效率。当我在第一个程序中像这样“(i = 2; i < Math.sqrt(number) + 1; i++)”增强for循环时,它不再打印出“YES!PRIME!”当你输入素数时。它给出一个空白。即使我之前的解释是正确的(可能不是),这也没有得到解释。

你可以启发我。

答案:int i is outside of scope of for-loop and after going through the for-loop multiple times upto number the value of i will reach the value number, when we can be sure it is a prime 。此外,在检查了消失的“YES!PRIME!”之后再次声明,事实证明实际上可以将 if 语句和 for 循环中的 number 更改为( Math.sqrt(number) + 1 )并具有工作代码。所以这个问题是基于一个错误的前提。

最佳答案

ifor 之外声明循环,因此它的值仍在范围内并且在循环后可用 完成(与比较数据类型或类似的事情无关!)。

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

当您执行 sqrt 时优化,改变循环的结束条件, 所以i == number循环退出后不再成立,即使该数字是质数。

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

关于java - 为什么这个主要检查器可以工作,但如果我试图提高它的效率却不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18391768/

相关文章:

java - 在 findNextPrime 方法中,为什么我们需要找到 'num' 的平方根,sqt,并在 for 循环中使用它?

java - 如何使用动态创建的类作为泛型?

c - C 中的质数

java - 三角测试仪

java - 设计一个类来判断一个数是否为素数

java - 在 LeetCode 质数挑战赛中找不到我的程序的修复程序

Java jstack 示例指向右括号而不是代码行

java - 本地 jar 不包含在类路径 (`<scope>system</scope>` 中)

java - 通过 lambda 表达式调用 System.out.println()