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



我的任务是用JAVA打印以3结尾的前N个素数,然后求和。"N〃;是一个输入。有什么建议吗?我是JAVA的新手,我对这个任务越来越着迷了。

例如,如果N是3,则以3结尾的前三个素数是
3
13
23

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

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

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

首先,您应该将N作为输入,并初始化一个类似于sum=0的变量。然后,按如下方式启动foor循环:

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

在循环中,您应该将i转换为字符串,这样您就可以使用

CCD_ 3以获得最后一个字符并与"0"进行比较;3〃;。如果它是一个";3〃;,使用另一个for循环,该循环从2开始到您正在比较的数字的一半,看看它是否可以被整除。如果是,则将其添加到";sum";变量,否则什么都没有。这就是它应该如何工作。我写完整的代码不是为了让你喜欢,但如果你需要,我会做的。

您需要遵循以下步骤:

  1. 获取从1到n的素数。

  2. 检查它的最后一个数字是否可以被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:

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

由于您是新手,让我们从基础知识开始。我想你知道循环,而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转换为字符串,这样交叉检查就很容易了。我在这里把素数(int数(和你的数字3(int结束(进行比较。这个方法可以集成到最终答案中,但我打破了它来简化事情。

现在作为压轴,我们应该打印素数的和。看看这个方法:

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

从用户那里获得输入是你的工作部分…:(

在我看来,您的任务适用于反应流。在您的情况下,您希望某个源发出一个[无限]整数流,并从这些发出的整数中捕获以3结尾的第一个N素数。

以下是您所需任务的两个实现。首先使用JDK9中首次添加的java.util.concurrent.Flow类。请注意,这是我第一次使用这个类,我找不到一个我能理解的例子,所以我几乎把它放大了。因此,我猜这对我来说是一个笨拙的努力。尽管如此,我还是想与社区分享。

首先是一个实现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在反应流方面起步较晚,而且有几个第三方库提供了实现。这些库在JDK9问世之前就已经存在,因此与JDK1.8等早期JDK版本兼容。下面是使用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");
}
}
}

以下是Python代码,显示0到100区间内以3结尾的所有素数

lower = 0
upper = 100
primelist=[]
for num in range(lower, upper + 1):
# all prime numbers are greater than 1
if num > 1:
for i in range(2, num):
if (num % i) == 0:
break
else:
strnum = str(num)
if strnum[-1] == '3':
primelist.append(num)

print(primelist)

输出

[3, 13, 23, 43, 53, 73, 83]

相关内容

最新更新