找出 2 到 N 之间的所有素数
厄拉多塞筛法
举个例子会很快明白这个算法
比如求出 2 - 15 的素数
现有一个原列表[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
第一轮:将首元素2
放入结果集并移出原列表,然后将2
的倍数移出原列表
result = [2], nums = [3, 5, 7, 9, 11, 13, 15]
第二轮:将首元素3
放入结果集并移出原列表,然后将3
的倍数移出原列表
result = [2, 3], nums = [5, 7, 11, 13]
第三轮:将首元素5
放入结果集并移出原列表,然后将5
的倍数移出原列表
result = [2, 3, 5], nums = [7, 11, 13]
第四轮:将首元素7
放入结果集并移出原列表,然后将7
的倍数移出原列表
result = [2, 3, 5, 7], nums = [11, 13]
第五轮:将首元素11
放入结果集并移出原列表,然后将11
的倍数移出原列表
result = [2, 3, 5, 7, 11], nums = [13]
第六轮:将首元素13
放入结果集并移出原列表,然后将13
的倍数移出原列表
result = [2, 3, 5, 7, 11, 13], nums = []
总结一句话就是每一轮将第一个元素移出并放入结果集,并移出该元素的倍数
最后当原列表为空时,结果集为所求素数集合
/**
* 找出 2 - n 中的所有素数
* 厄拉多塞筛法
* 先将2到n添加到集合, 然后从第一个元素开始
* 将该元素从源集合移到结果集, 将可以被该元素整除的元素移出源集合
* 一轮后, 再次从现存的第一个元素开始重复上述操作
* 直到源集合为空时, 结果集为所求素数集合
*
* @param n 最大值
* @return java.util.List<java.lang.Integer>
*/
public static List<Integer> findPrimeNumber(int n) throws Exception {
if (n < 2) {
throw new Exception("最小素数为2");
} else {
// 结果集
List<Integer> result = new LinkedList<>();
// 源数据集
List<Integer> original = new LinkedList<>();
// 将2到n添加到 original
for (int i = 2; i <= n; i++) {
original.add(i);
}
// 当源数组不为空时
while (original.size() != 0) {
// 取出当前的第一个数作为这一轮的除数
Integer divisor = original.get(0);
// 该除数作为结果添加到结果集, 并移除
result.add(original.remove(0));
// 移出所有能被该除数整除的
for (int i = 0; original.size() > 0 && i < original.size(); ) {
if (original.get(i) % divisor == 0) {
original.remove(i);
} else {
i++;
}
}
}
return result;
}
}