素数发生器逻辑 [英] Prime Number Generator Logic

查看:87
本文介绍了素数发生器逻辑的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am supposed to make a class PrimeNumberGenerator which has a method nextPrime that will print out all prime numbers up to a number the user inputs.

Ex)

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

我们的老师告诉我们,我们应该使用嵌套环。我试过了,但是当我试图制作内部(嵌套)循环时,我真的很困惑。

Our teacher told us that we should use a nested for loop. I tried, but when I tried to make the inner (nested) loop, I got really confused.

这是我的代码:
(我稍后会做一个测试课)

Here is my code: (I'm going to make a tester class later)

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;
    }

}


推荐答案

这里有两个你忘了问的问题:

There are two questions here that you have forgotten to ask:


  • 为什么嵌套循环会让一切变得如此复杂?

  • 我可以做些什么来使事情再次复杂化?

让我们一起玩你实际问的问题,然后回答前两个问题。

So let's play along with the question you actually asked, and then answer the first two questions.

您想要做的事情可能如下所示:
对于每个数字,1-n,其中n由用户输入,如果它是素数则打印出来。

What you want to do can probably be described as such: For every number, 1-n, where n is input by the user, print it if it's prime.

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

Okay, so let's write up the pseudocode/logic here. It looks like Java, but it isn't. It's just meant to convey what we're going for:

int largestNumber = readIntegerFromKeyboard();

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

所以让我们这样做吧!但首先,我们需要一份我们需要做的所有事情的洗衣清单:

So let's do this! But first, we need a laundry-list of all the things we need to do:


  • 从键盘读取整数

  • 循环数字

  • 检查数字是否为素数

  • 打印质数(带换行符)

  • read integer from keyboard
  • loop over numbers
  • check if the number is a prime
  • print primes (with newlines)

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

Let's just do the two easy things first. Reading the input and setting up the loop:

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时,一切都将变得混乱且难以阅读。

Okay, that seems simple enough. So far, everything here makes sense. It's easy to understand the logic. Now however, when we replace isPrime with actual logic, everything is about to get cluttered and hard to read.

所以让我们编写这段代码,因为它易于理解尽可能。我们将不使用任何技巧来加速代码。可读性和正确性是唯一我们将关心的两件事。我们将使用模运算符来检查某些东西是否可以均匀分割。 Modulo就像整数除法,除了它返回余数而不是结果。所以7/2 = 2. 7%2 = 1,因为剩下一个。

So let's write this code as easy to understand as possible. We will use no tricks to speed up the code. Readability and correctness are the only two things we will care about. We will use the modulo operator to check if something is evenly dividable. Modulo is like integer division, except that it returns the remainder and not the result. so 7 / 2 = 2. 7 % 2 = 1, because there's one left over.

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);
    }
}    

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

So the good news is, this works. The bad news is, this is harder to read than necessary. And it's not a lot we can do here. When I wrote this up, I made several stupid mistakes, mixing up the variables. Maybe I'm stupid. So maybe I should in that case write stupid-proof code. ;) You on the other hand is not stupid. But you may work with me, who is stupid, so you kind of have to write stupid-proof code yourself, so that you can productively work with me.

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

The big problem is that we have this massive loop in the middle of the other loop. This is what tripped me up. I referred to the wrong loop variable. But why do we need a loop in a loop? Wasn't it much more comfortable to read:

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

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

Instead of that whole mess? Your professor pointed out the nested loops. But it threw you off. Instead, just write the isPrime method. And the fact is, that this is true for every single instance of nested loops I have ever come across.. So let's see how that would look instead:

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;
    }
}

这对我来说更容易阅读。不是因为逻辑变得更容易,而是因为 我不得不关心的事情是:

That to me is a whole lot easier to read. Not because the logic got easier, but because the only thing I had to care about was either:


  • 检查所有数字并打印正确的数字,或

  • 如何检查数字是否为素数。

由于这两个独立的东西现在是分开的,所以你可以立刻想一想。高兴,因为你刚刚做了一个适当的抽象。这使您的代码更容易理解,因为它分离出两个问题。这是制作大型项目的关键方式。你采取困难的事情并自己做。然后你可以自己测试它们,并自己使用它们。

Since these two separate things are now apart, you have much less to think about at once. Rejoice, for you have just done a proper abstraction. This makes your code easier to understand, because it separates out the two concerns. This is a key way of making larger projects. You take difficult things and do them by themselves. Then you can test them by themselves, and use them by themselves.

(现在我只需要等待回答你没有明确要求的问题的誓言......)

(Now I only have to await the downvotes for answering a question you didn't explicitly ask...)

这篇关于素数发生器逻辑的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆