这个 Eratosthenes Sieve 实现在内部是如何工作的?

How is this Eratosthenes Sieve implementation is working internally?

提问人:Brando Jeanpier 提问时间:10/21/2022 最后编辑:Brando Jeanpier 更新时间:10/22/2022 访问量:80

问:

我发现这段代码似乎是伊拉斯托森之筛的非最佳版本,它将 N 个前素数放入数组中。

private IntPredicate p = x -> true;

private int[] primes(int n) {
    
    return IntStream.iterate(2, i -> i + 1)
        .filter(x -> p.test(x))
        .peek(i -> p = p.and(k -> k % i != 0))
        .limit(n)
        .toArray();
}

内部发生了什么?IntPredicate

java-stream primes sieve intstream

评论

0赞 Brando Jeanpier 10/21/2022
@AlexanderIvanchenko实际上,如果我只是在过滤器方法中放置一个真正的文字,或者只是删除过滤器方法,我会得到不同的输入,可能是我应该添加输出结果。
0赞 Alexander Ivanchenko 10/21/2022
我没有看到谓词因格式而被更改。peek()
1赞 Will Ness 10/22/2022
必须注意的是,这不是埃拉托色尼的筛子,而是按素数试除的筛子的非最优版本。
0赞 Brando Jeanpier 10/22/2022
@WillNess,它如何成为伊拉斯托森尼筛子的最佳版本?我找不到 Java 中的实现。
2赞 Holger 10/25/2022
@Brando Jeanpier 中,您可以在此答案的中间找到 Sieve of Eratosthenes 的 Java 实现

答:

4赞 Alexander Ivanchenko 10/21/2022 #1

此代码通过 IntPredicate.and() 方法生成一个聚合谓词,其工作方式如下:

p = x -> true; // for first stream element `2` - 
               //   which passes the predicate p

// Predicate p is being reassigned while
// peek() sees the element `2`, to
p = x -> true && x % 2 != 0

// The next stream element `3` passes the updated predicate
// And the predicate is being reassigned again while
// peek() sees the element `3` to

p = x -> true && x % 2 != 0 && x % 3 != 0

// And so on...

因此,每个成功传递的元素都会通过“逻辑 AND”将新条件附加到当前谓词中。filter&&

在流执行结束时,谓词将包含一些条件,这些条件将给定数字与结果中存在的所有质数进行检查。

请注意,这个 hacky 实现已损坏:

peek() 是专门为支持调试而引入的操作。它不用于执行可能影响执行结果的操作。 不保证在并行执行时调用它的顺序,并且在某些情况下可以进行优化。peek