【问题标题】:Sieve of Eratosthenes, generating primes. Problem with loops埃拉托色尼筛,生成素数。循环问题
【发布时间】:2023-04-02 21:32:01
【问题描述】:

我正在尝试使用埃拉托色尼筛算法生成 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])));
    }
    
}

【问题讨论】:

  • 您不想在迭代时从 List 中删除元素。最好使用您要删除的元素构建一个单独的List,然后使用removeAll() 方法。

标签: java loops nested-loops primes sieve-of-eratosthenes


【解决方案1】:

这就是 埃拉托色尼筛法 的工作原理,它不断标记范围内除自身之外的所有 prime 数字的倍数。
例如,当我们以 i=2 开头时,我们将 4、6、8、10、12、... 标记为 composite 数字。
对于i=3,它会将 6、9、12、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]

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-12-16
  • 2013-10-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多