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

sz81bmfz  于 2021-07-03  发布在  Java
关注(0)|答案(5)|浏览(258)

我的任务是用java打印以3结尾的前n个素数,然后求和。”n”是一个输入。有什么建议吗?我是java的新手,我对这个任务很着迷。
例如,如果n是3,那么以3结尾的前三个素数是

13
23
所以我的程序需要打印这三个数字以及这三个数字的总和(即39)。

busg9geu

busg9geu1#

既然你是新来的,让我们从基础开始。我假设您知道for循环,而java中的循环和数组。
首先我们需要检查一个数是否是素数。有许多高级方法(如果您感兴趣,请检查以下内容:https://github.com/google/guava/blob/ef0ce9216a991ea40774ef82f4fd3ea255c48597/android/guava/src/com/google/common/math/longmath.java#l1003)但现在我们还是坚持基本原则吧。
看看这个代码。它检查一个数字是否是素数。

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

这种方法相当基本。我从这里得到了这个方法(https://www.java67.com/2014/01/how-to-check-if-given-number-is-prime.html)
正如我在评论中所说的,这些方法已经在互联网上出现了。
现在我们应该找到以3结尾的素数。看看这个方法。

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

它使用内置的 String.valueOf() 把int转换成string这样交叉检查就很容易了。我把素数(int number)和你的3(int 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;
}

我使用外部for循环作为计数器,它的计数可达n,而内部while循环用于搜索与我们的参数匹配的素数。
如果你把所有的方法结合起来,你就会得到答案(正如我在评论中所说的)

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

获取用户的输入是您的工作内容……:)

dvtswwa3

dvtswwa32#

把你的问题分成更小的子问题。你可以从一个简单的算法开始寻找素数。然后在此基础上构建您的需求。

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

smdnsysy3#

在我看来,你的任务适合于React流。在您的例子中,您希望某个源发出一个[无限]整数流,并从这些发出的整数中捕获以3结尾的前n个素数。
下面是您所需任务的两个实现。首先使用类java.util.concurrent.flow,该类首先添加到JDK9中。请注意,这是我第一次使用这个类,我找不到一个我能理解的例子,所以我非常喜欢它。因此,我猜这是我的笨拙努力。尽管如此,我还是想和社区分享。
首先是一个实现 Subscriber 接口。

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

注意上面的类有一个 main() 方法,因此它是运行此实现时要启动的类。
下一个 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;
    }
}

最后是 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;
    }
}

当然,jdk对reactivestreams第三方来说来得晚,而且有几个第三方库提供了实现。这些库在jdk9出现之前就存在了,因此与早期的jdk版本(如jdk1.8)兼容。下面是使用rxjava的任务实现,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");
        }
    }
}
5lhxktic

5lhxktic4#

首先,你应该 N 作为输入并初始化这样的变量 sum=0 . 然后,开始foor循环,如下所示:

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

}

在循环中,你应该把i转换成一个字符串,这样你就可以使用 string.substring(string.length()-1) 获取最后一个字符并与“3”进行比较。如果是“3”,则使用另一个for循环,从2开始到所比较数字的一半,以查看该循环是否可整除。如果是这样,将其添加到“sum”变量中,否则什么都不做。这就是它的工作原理。我写完整的代码不是为了让你享受它,但如果你需要,我会做的。

cmssoen2

cmssoen25#

您需要遵循以下步骤:
得到从1到n的素数。
检查它的最后一位是否可以被3整除。如果是,则添加值。

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

//将java8 intstream api与range方法结合使用:

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

相关问题