简体   繁体   English

如何使用 FOR 循环打印前 N 个以 3 结尾的素数?

[英]How can I print the first N prime numbers ending with 3 using a FOR loop?

My task is to print with JAVA the first N prime numbers that ends in 3 and then sum them.我的任务是用 JAVA 打印以 3 结尾的前 N 个素数,然后将它们相加。 "N" is an input. “N”是一个输入。 Any advice?有什么建议吗? I'm newbie with JAVA and I'm getting crazy with this task.我是 JAVA 的新手,我对这项任务感到疯狂。

For example, if N is 3, then the first three prime numbers that end in 3 are例如,如果 N 是 3,那么以 3 结尾的前三个素数是
3 3
13 13
23 23

So my program needs to print those three numbers as well as the sum of those three numbers (which is 39).所以我的程序需要打印这三个数字以及这三个数字的总和(即 39)。

Split your problem into smaller sub-problems.将您的问题拆分为更小的子问题。 You can start with a simple algorithm to find primes.您可以从一个简单的算法开始找到素数。 Then build your requirement on top of that.然后在此基础上构建您的要求。

package example;

import java.util.stream.IntStream;

public class Example {

    public static void main(String[] args) {
        final int N = 3;

        int sumOfTheFirstNPrimesEndingWith3 = primes()// generates a stream of primes (see below)
            .filter(v -> v % 10 == 3)// filter for the primes ending with 3
            .limit(N)// limit to N
            .sum();
    }

    public static IntStream primes() {
        return IntStream.iterate(1, v -> v += 2)// generate an infinite stream of Ints starting at 1, incrementing by 2
            .skip(1L)// skip the fist generated number since we know 1 is not a prime
            .filter(Example::isPrime);// filter primes
    }

    public static boolean isPrime(int num) {
        return IntStream.iterate(num / 2, v -> v > 1, v -> --v)// generate a stream of ints, starting at num / 2 until (exclusive) 1
            .noneMatch(v -> num % v == 0);// check if our number "num" is dividable by the number in our stream
    }
}

To begin, you should take N as input and initialize a variable like this sum=0 .首先,您应该将N作为输入并初始化这样的变量sum=0 Then, start your foor loop as follows:然后,按如下方式启动您的 for 循环:

for (int i=0;i<N;i++){

}

Inside the loop you should cast your i into a String, so you can use在循环内,您应该将 i 转换为字符串,这样您就可以使用

string.substring(string.length()-1) to get the last char and compare with "3". string.substring(string.length()-1)获取最后一个字符并与“3”进行比较。 If it's a "3", use another for loop that starts from 2 to the half of the number you are comparing, to see if that is divisible.如果它是“3”,请使用另一个从 2 开始到要比较的数字的一半的 for 循环,看看它是否可整除。 If so, add it to "sum" variable, else nothing.如果是这样,将其添加到“sum”变量中,否则什么都没有。 That's how it should work.这就是它应该如何工作的方式。 I'm not writing the full code to let you enjoy it, but if you need, I'll do it.我不是为了让你享受它而编写完整的代码,但如果你需要,我会这样做。

You need to follow below steps:您需要按照以下步骤操作:

  1. Get the prime numbers from 1 to n.获取从 1 到 n 的素数。

  2. Check whether it's last digit is divisible by 3 or not.检查它的最后一位数字是否可以被3整除。 If yes, add the value.如果是,请添加该值。

     private static void getPrimeNumbers(int n) { int sum = 0; for (int i = 1; i < n; i++) { if (hasNoFactors(i)) { String str = String.valueOf("" + i); if (Integer.valueOf(str.substring(str.length() - 1)) == 3) { sum = sum + i; } } } System.out.println("sum: "+sum); }

// Use Java8 Intstream API with range method: // 使用 Java8 Intstream API 和 range 方法:

    private static boolean hasNoFactors(int number) {
    return IntStream.range(2, number).noneMatch(f -> number % f == 0);
    }

Since you are a newcomer, lets start with the basics.由于您是新手,让我们从基础开始。 I assume you know for loops, while loops and arrays in java.我假设你知道 java 中的 for 循环、while 循环和 arrays。

First we need to check if a number is a prime or not.首先我们需要检查一个数字是否是素数。 There are many advanced ways (Check this if you are interested: https://github.com/google/guava/blob/ef0ce9216a991ea40774ef82f4fd3ea255c48597/android/guava/src/com/google/common/math/LongMath.java#L1003 ) but lets stick to the basics for now.有很多高级方法(如果您有兴趣,请查看: https://github.com/google/guava/blob/ef0ce9216a991ea40774ef82f4fd3ea255c48597/android/guava/src/com/google/common/math/LongMath.java#L1003但是)现在让我们坚持基础知识。

Check out this code.查看此代码。 It checks if a number is prime or not.它检查一个数字是否是素数。

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

This method is fairly basic.这种方法是相当基本的。 I got this method from here ( https://www.java67.com/2014/01/how-to-check-if-given-number-is-prime.html )我从这里得到了这个方法( https://www.java67.com/2014/01/how-to-check-if-given-number-is-prime.html

As I told in the comments, these methods are already on the internet.正如我在评论中所说,这些方法已经在互联网上。

Now we should find the primes which ends in 3. Check out this method.现在我们应该找到以 3 结尾的素数。看看这个方法。

public static boolean doesEndsWith(int number, int end) {
        return String.valueOf(number).endsWith(String.valueOf(end));
}

This uses the built-in String.valueOf() to convert int to string so cross checking would be easy.这使用内置的String.valueOf()将 int 转换为字符串,因此交叉检查很容易。 I check the prime number (int number) against your number 3 (int end) here.我在这里检查素数(整数)和你的数字 3(整数)。 This method can be integrated into final answer but I broken it to simplify things.这种方法可以集成到最终答案中,但我打破它以简化事情。

Now as a finale, we should print the sum of the primes.现在作为结局,我们应该打印素数的总和。 Check out this method:看看这个方法:

public static int sumOfFilteredPrimes(int N) {
    int sum = 0;
    int i = 1;
    for (int j = 0; j < N; j++) {
        while (true) {
            if (isPrimeNumber(i) && doesEndsWith(i, 3)) {
                sum += i;
                i++;
                break;
            } else i++;
        }
    }
    return sum;
}

I use outer for loop as a counter which counts upto N, and inner while loop to search for prime numbers which match our parameters.我使用外部 for 循环作为计数到 N 的计数器,使用内部 while 循环来搜索与我们的参数匹配的素数。

If you combine all methods, you get the answer (As I said in the comments)如果你结合所有方法,你会得到答案(正如我在评论中所说)

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

        System.out.println(sumOfFilteredPrimes(3));

    }

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

    public static boolean doesEndsWith(int number, int end) {
        return String.valueOf(number).endsWith(String.valueOf(end));
    }

    public static int sumOfFilteredPrimes(int N) {
        int sum = 0;
        int i = 1;
        for (int j = 0; j < N; j++) {
            while (true) {
                if (isPrimeNumber(i) && doesEndsWith(i, 3)) {
                    sum += i;
                    i++;
                    break;
                } else i++;
            }
        }
        return sum;
    }
}

Getting input from user is your part to work on... :)从用户那里获取输入是您的工作职责...... :)

Your task lends itself to reactive streams , in my opinion.在我看来,您的任务适用于响应式流 In your case, you want some source to emit a [infinite] stream of integers and from those emitted integers you want to capture the first N prime numbers that end in 3.在您的情况下,您希望某个源发出 [infinite] stream 整数,并从这些发出的整数中捕获以 3 结尾的前N个素数。

Below are two implementations of your required task.以下是您所需任务的两个实现。 First using class java.util.concurrent.Flow which was first added in JDK 9. Note that this is the first time I have used this class and I couldn't find an example that I understood so I pretty much winged it.首先使用 JDK 9 中首次添加的 class java.util.concurrent.Flow 。请注意,这是我第一次使用这个 class 的例子,我几乎无法理解,所以找不到它。 As a result, I'm guessing it's a clumsy effort on my part.结果,我猜这对我来说是一个笨拙的努力。 Nonetheless I wanted to share it with the community.尽管如此,我还是想与社区分享。

First a class that implements the Subscriber interface.首先是实现Subscriber接口的 class。

import java.util.concurrent.Flow;

public class Subscrib implements Flow.Subscriber<Integer> {
    private int  number;
    private int  sum;
    private long  counter;
    private Flow.Subscription  subscription;

    public Subscrib(int n) {
        number = n;
    }

    @Override
    public void onSubscribe(Flow.Subscription subscription) {
        this.subscription = subscription;
        subscription.request(counter++);
    }

    @Override
    public void onNext(Integer item) {
        System.out.println(item);
        sum += item.intValue();
        if (counter == number) {
            subscription.cancel();
        }
        else {
            subscription.request(counter++);
        }
    }

    @Override
    public void onError(Throwable throwable) {
        throwable.printStackTrace();
    }

    @Override
    public void onComplete() {
        System.out.println("sum = " + sum);
    }

    public static void main(String[] args) {
        if (args.length > 0) {
            int n = Integer.parseInt(args[0]);
            System.out.printf("n = %d%n", n);
            new Publishe().subscribe(new Subscrib(n));
        }
        else {
            System.out.println("ARGS: <total number of primes>");
        }
    }
}

Note that the above class has a main() method and so it is the class to launch when running this implementation.请注意,上面的 class 有一个main()方法,因此在运行此实现时要启动 class。

Next the Publisher implementation.接下来是Publisher实现。

import java.util.concurrent.Flow;

public class Publishe implements Flow.Publisher<Integer> {
    Flow.Subscriber<? super Integer>  subscriber;

    @Override
    public void subscribe(Flow.Subscriber<? super Integer> subscriber) {
        this.subscriber = subscriber;
        subscriber.onSubscribe(new Subscrip(this));
    }

    public Flow.Subscriber<? super Integer> getSubscriber() {
        return subscriber;
    }
}

Finally, the Subscription implementation.最后是Subscription实现。

import java.util.concurrent.Flow;

public class Subscrip implements Flow.Subscription {
    private int  last;
    private Publishe publishe;

    public Subscrip(Publishe publishe) {
        this.publishe = publishe;
        last = 1;
    }

    @Override
    public void request(long n) {
        if (last == 0) {
            publishe.getSubscriber().onError(new RuntimeException("Exhausted"));
        }
        else {
            last = getNextPrime();
            publishe.getSubscriber().onNext(Integer.valueOf(last));
        }
    }

    @Override
    public void cancel() {
        publishe.getSubscriber().onComplete();
    }

    private int getNextPrime() {
        int count = last + 1;
        while (count < Integer.MAX_VALUE) {
            if (isCandidate(count)) {
                break;
            }
            count++;
        }
        if (count == Integer.MAX_VALUE) {
            count = 0;
        }
        return count;
    }

    private boolean isCandidate(int x) {
        return isPrime(x)  &&  x % 10 == 3;
    }

    private boolean isPrime(int x) {
        boolean isPrime = true;
        double root = Math.sqrt(x);
        root = Math.floor(root);
        int limit = Math.round((float) root);
        for (int i = 2; i < limit; i++) {
            if (x % i == 0) {
                isPrime = false;
                break;
            }
        }
        return isPrime;
    }
}

Of-course the JDK arrived late to the reactive streams party and there are several, third-party libraries that provide implementations.当然,JDK 迟到了响应式流派对,并且有几个提供实现的第三方库。 These libraries existed before JDK 9 came out and so are compatible with earlier JDK versions, like JDK 1.8.这些库在 JDK 9 出现之前就已经存在,因此与早期的 JDK 版本(如 JDK 1.8)兼容。 Below is an implementation of your task that uses RxJava which has a much simpler (and richer) API.下面是一个使用RxJava的任务实现,它具有更简单(更丰富)的 API。

import io.reactivex.rxjava3.core.Observable;

public class PrimeNos {
    private static boolean isPrime(long x) {
        boolean isPrime = true;
        double root = Math.sqrt(x);
        root = Math.floor(root);
        int limit = Math.round((float) root);
        for (int i = 2; i < limit; i++) {
            if (x % i == 0) {
                isPrime = false;
                break;
            }
        }
        return isPrime;
    }

    public static void main(String[] args) {
        if (args.length > 0) {
            int n = Integer.parseInt(args[0]);
            long[] sum = new long[1];
            Observable.range(2, Integer.MAX_VALUE - 1)
                      .filter(x -> isPrime(x))
                      .filter(x -> x % 10 == 3)
                      .take(n)
                      .subscribe(x -> {System.out.println(x); sum[0] += x;},
                                 t -> t.printStackTrace(),
                                 () -> System.out.println("sum = " + sum[0]));
        }
        else {
            System.out.println("ARGS: N");
        }
    }
}

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

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