素数生成器逻辑 - java

我应该创建一个类PrimeNumberGenerator,该类具有方法nextPrime,该方法将打印出所有质数,直至用户输入的数字。

例)

Enter a Number: 
20
2
3
5
7
11
13
17
19

老师告诉我们,我们应该使用嵌套的for循环。我尝试过,但是当我尝试进行内部(嵌套)循环时,我真的很困惑。

这是我的代码:
(我稍后将进行测试人员课程)

public class PrimeGenerator {

    private int num;
    boolean isPrime;

    public PrimeGenerator(int n)
    {
        num = n;
    }

    public int nextPrime (int num)
    {
        for (int i=2; i < num; i++) // The first prime number is 2 and the prime numbers only have to go up to a number the user inputs. 
        {
            for (int j = 3; j<=i/2; j+=2) // The next prime number is 3 and I attempted to loop through to get the next odd number.
            {
                if (num % i == 0) //if the number (upper limit) mod a "prime number" is 0, then that means that number is not really "prime" after all. 
                {
                    break;
                }
            }
        }

        return num;
    }

}

参考方案

您忘记了这里有两个问题:

为什么嵌套循环使所有事情变得如此复杂?
我该怎么做才能使事情变得简单?

因此,让我们处理您实际提出的问题,然后回答前两个问题。

您想要做的事情可能描述如下:
对于每个数字1-n(用户输入n),请打印它的质数。

好的,让我们在这里编写伪代码/逻辑。
它看起来像Java,但事实并非如此。这只是为了传达我们的目标:

int largestNumber = readIntegerFromKeyboard();

for all ints i from 1 to largestNumber {
    if(isPrime(i)) {
        println(i);
    }
}

所以,让我们做吧!但是首先,我们需要列出所有需要做的事情的清单:

从键盘读取整数
遍历数字
检查数字是否为素数
打印素数(带有换行符)

让我们先做两个简单的事情。读取输入并设置循环:

Scanner keyboard = new Scanner(System.in);
int largestNumber = keyboard.nextInt();

for(int i = 1; i <= largestNumber; ++i) {
    if(isPrime(i)) {
        System.out.println(i);
    }
}    

keyboard.close();

好的,这似乎很简单。到目前为止,这里的一切都有意义。逻辑很容易理解。
但是,现在,当我们用实际的逻辑替换isPrime时,一切都将变得混乱且难以阅读。

因此,让我们编写尽可能容易理解的代码。我们将不使用任何技巧来加速代码。可读性和正确性是我们唯一关心的两件事。我们将使用模运算符来检查某些事物是否可以平均划分。模数类似于整数除法,只不过它返回余数而不是结果。所以7/2 =2。7%2 = 1,因为还剩一个。

Scanner keyboard = new Scanner(System.in);
int largestNumber = keyboard.nextInt();

for(int i = 1; i <= largestNumber; ++i) {
    // checks if the number is a prime or not
    boolean isPrime = true;
    for(int check = 2; check < i; ++check) {
        if(i % check == 0) {
            isPrime = false;
        }
    }
    if(isPrime) {
        System.out.println(i);
    }
}    

好消息是,这可行。
坏消息是,这比必要的要难读。我们在这里可以做的很多。当我写这篇文章时,我犯了几个愚蠢的错误,混淆了变量。也许我很傻。因此,在那种情况下,也许我应该编写愚蠢的代码。 ;)另一方面,您并不傻。但是您可能与愚蠢的我一起工作,因此您必须自己编写防愚蠢的代码,这样您才能与我高效地工作。

最大的问题是我们在另一个循环的中间有一个巨大的循环。这就是让我震惊的原因。我提到了错误的循环变量。但是为什么我们需要一个循环呢?读起来不是很舒服吗?

if(isPrime(i)) {
    System.out.println(i);
}

而不是整个混乱?您的教授指出了嵌套循环。但这把你甩了。相反,只需编写isPrime方法。事实是,对于我碰到的每个嵌套循环实例,都是如此。所以让我们看一下它的外观:

class Homework {
    public static void main(String[] args) {
        Scanner keyboard = new Scanner(System.in);
        int largestNumber = keyboard.nextInt();

        for(int i = 1; i <= largestNumber; ++i) {
            if(isPrime(i)) {
                System.out.println(i);
            }
        }
        keyboard.close();
    }

    /**
     * Checks is a positive integer is a prime number
     */
    public static boolean isPrime(int number) {
        for(int check = 2; check < number; ++check) {
            if(number % check == 0) {
                return false;
            }
        }
        return true;
    }
}

对我而言,这很容易阅读。不是因为逻辑变得更容易,而是因为我唯一需要关心的是:

检查所有数字并打印正确的数字,或者
如何检查数字是否为质数。

由于这两个分开的事物现在分开了,因此您无需过多考虑。欢喜,因为您刚刚进行了适当的抽象。这使您的代码更容易理解,因为它将两个问题分开了。这是进行大型项目的关键方法。您要处理困难的事情,然后自己去做。然后,您可以自己测试它们,并单独使用它们。

(现在,我只需要等待下一次投票即可回答您未明确提出的问题...)

JAVA:字节码和二进制有什么区别? - java

java字节代码(已编译的语言,也称为目标代码)与机器代码(当前计算机的本机代码)之间有什么区别?我读过一些书,他们将字节码称为二进制指令,但我不知道为什么。 参考方案 字节码是独立于平台的,在Windows中运行的编译器编译的字节码仍将在linux / unix / mac中运行。机器代码是特定于平台的,如果在Windows x86中编译,则它将仅在Win…

java:继承 - java

有哪些替代继承的方法? java大神给出的解决方案 有效的Java:偏重于继承而不是继承。 (这实际上也来自“四人帮”)。他提出的理由是,如果扩展类未明确设计为继承,则继承会引起很多不正常的副作用。例如,对super.someMethod()的任何调用都可以引导您通过未知代码的意外路径。取而代之的是,持有对本来应该扩展的类的引用,然后委托给它。这是与Eric…

Java:BigInteger,如何通过OutputStream编写它 - java

我想将BigInteger写入文件。做这个的最好方式是什么。当然,我想从输入流中读取(使用程序,而不是人工)。我必须使用ObjectOutputStream还是有更好的方法?目的是使用尽可能少的字节。谢谢马丁 参考方案 Java序列化(ObjectOutputStream / ObjectInputStream)是将对象序列化为八位字节序列的一种通用方法。但…

Java DefaultSslContextFactory密钥库动态更新 - java

我有一个使用org.restlet.engine.ssl.DefaultSslContextFactory的现有应用程序和一个在服务器启动时加载的密钥库文件。我有另一个应用程序,该应用程序创建必须添加的证书服务器运行时动态地更新到密钥库文件。为此,我在代码中创建了证书和私钥,然后将其写入到目录。该目录由bash脚本监视,该脚本检查是否有新文件,如果出现,它将…

Java-如何将此字符串转换为日期? - java

我从服务器收到此消息,我不明白T和Z的含义,2012-08-24T09:59:59Z将此字符串转换为Date对象的正确SimpleDateFormat模式是什么? java大神给出的解决方案 这是ISO 8601标准。您可以使用SimpleDateFormat simpleFormat = new SimpleDateFormat("yyyy-MM…