微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

埃拉托色尼筛,生成素数循环问题

如何解决埃拉托色尼筛,生成素数循环问题

我正在尝试使用埃拉托色尼筛算法生成 n 个素数。我调试了它,看到它在某个时候开始删除已经删除的数字。我不知道是什么问题,但我敢打赌这与我的循环有关。你能帮忙吗?

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class Part6 {

    public static List<Integer> primeSequence(int n) {
        List<Integer> list = IntStream.range(2,n).Boxed().collect(Collectors.toList());

        for (int i = 2; i <= list.size(); i++) {
            for (int j = i + 1; j <= list.size(); j++) {
            if(j % i == 0)
                list.remove(j);
            }
        }
       return  list;
        }


    public static void main(String[] args) {
        System.out.println(primeSequence(Integer.parseInt(args[0])));
    }
    
}

解决方法

这就是埃拉托色尼筛网的工作原理,它不断标记范围内除自身之外的所有 prime 数的倍数。
例如,当我们以 i=2 开头时,我们将 4,6,8,10,12,... 标记为 composite 数字。
同样对于 i=3,它会将 6,9,15,... 标记为非质数。
请注意 612 被标记了两次。还有更多的数字将被多次标记为复合。因此这是正常的。

现在,上面的程序有很多问题:

  1. 当您执行 list.remove(j) 时,它实际上删除了索引 j 处的数字,而不是数字 j 本身。因此,要删除合数 j,我们需要使用 Integer.valueOf(j)
  2. 循环的上限不应该是 list.size(),因为列表的大小会随着我们不断删除数字而不断减小。因此,将遗漏许多数字。

以下是您的代码的修改版本:

        for (int i = 2; i < n; i++)
        {
            for (int j = i + 1; j <= n; j++)
            {
                if (j % i == 0)
                {
                    list.remove(Integer.valueOf(j));
                }
            }
            System.out.println(list);
        }

输入:100
输出:

[2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97]

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。