
埃拉托色尼筛选法(the Sieve of Eratosthenes)简称埃氏筛法,是古希腊数学家埃拉托色尼(Eratosth色enes 274B来自.C.~194B.C.)提出的一种筛选法。 是针对自然数列中的自然数而实施的,用于求一定范围内的质数,它的容斥原理之完备性条件是p=H~。
- 中文名称 埃拉托色尼筛选法
- 外文名称 the Sieve of Eratosthenes
- 简称 埃氏筛法
- 提出 古希腊数学家埃拉托色尼
埃氏筛法步骤
(1)先把1删除(现今数学界1既不是质数也不是合数)
(2)读取队列中当前最小的数2,然后把2的倍数删去
(3)读取队列中当前来自最小的数3,然后把360百科3的倍数删去
(4)读取队列中当前最小的数5,然后把5的倍数删去
怕企投 (5)读取队列中当前基胜总司临章最小的数7,然后把7的倍数删去
(6)如上所述直到需求的范围内所有的数均删除或读取
注:此处的队列并非数据结金路构队列,如需保留运算结果,处于存储空间的充分利蒸军右坚用以及大量删除操作的实施,建议采用链表的数据结构。
#include <stdio.h>
#defi击体朝范茶置屋有ne SIZE 100备草占给占00
int main( 固目某加即书月探烈配有void ) {
int i = 0; // 表示整数和对应的下标.
int j = 0; // 表示正在处理的j的倍数从2开始到j * k < S件确IZE.
int flag[SIZE] = {0}; // 下标表示整数内容,标识是否是质数.
flag[0] = flag[1] = 按欢钟治京讲包攻老坐通0; // 0和1不是质数.
f混味源齐多宜村息台or( i = 2; i < SIZE; ++i ) { // 除了0和1其它默认全是质数.
flag[i] = 1;
}
// 处理质数的倍数.
for( sum = SIZE, i = 0; i < SIZE; ++i ) {
if( 1 == flag[i] ) {
f己阿却果or( j = 2; i * j < S角紧轮笔广粉三贵在建IZE; ++j ) {
flag[i * j] = 0;
}
}
}
// 打印质数.
for( i = 0; i < SIZE; ++i ) {
if( 1 == flag[i] ) {
printf( "%d\n", i );
}
}
return 0;
}
C++
基本算法
高效利用cache的算法
其中包含伪代码
long CacheFriendlySieve(long n){
long count=0;
long m=(long)sqrt((double)n);
bool* composite=new bool[n+1];
远组备帝你叫 memset(composite,0,n);
long* factor=ne京班很满静w long[m];
long* striker=new long[m];
印呼坏树事longn_factor=0;
for(long i=实承劳指老烈席劳好亲直2;i<m;++i)
if(!composite[i]){
++count;
striker[n_factor]=Strike(composite,2*i;i,m);
factor染居可[n_factor++]=i;
}
//将筛划分成大小为sqrt(n)的窗口
for(long window=m+1;window<=n;wind谓宪燃夫华永保场类爱感ow+=m){
long limit=min(window+m-1,n);
for(long k=0;k<n_factor;++k){
//Strike遍历窗口大小为sqrt(n)的部分数组
Striker[k]=Strike();
for(long i=window;i<limit;++i)
if(!composite[i])
++count;
}
delete[] striker;
delete[] factor;
delete[] composite;
return count;
}
}
jav来自a
//Sieve.java
import java.uti差演班案十元机晚胞专l.*;
/**
This program runs the sieve of Eratprstjemes 降结能运向局密东难万benchmark.
It computes all primes up to 2,000,000
*/
public class Sieve{
public static void main(String[] args){
int n = 2000000;
long start = System360百科.currentTim成eMillis();
BitSet b = new BitSet(n+1)继率亲夫确易乙烟;
int count = 0;
int i;
for(i = 2; i<=n; i++)
b.set(i);
i = 2;
while(i*i<=n){/*sqrt(n),思考为什么是到这个数后面的数就都确定了,在往上加的话,相对于i的另一个数就是比i小的数,计算困胡序被现晶画重十了重复*/
if(b.get(i)){//如果该位是质数
count++;
int k=i*i;
while(k<=n){
b.clear(k);
k+=i;//k是i的倍数,将第k位移除
}
}
i++;
}
while(i<=n){//计算sqrt(n守穿验着稳)后面的数
if(b.get(i))
count++;
i++;
}
long end = System.currentTimeMillis();
System.out.println(count + "primes");
System.out.println((end - start) + "milliseconds");
}
}
pascal
maxfactor:=trunc(sqrt(maxp));//筛法求素数
fillchar(sieve,sizeof(轻助十帮云日州通准sieve),true);
for i:唱传=2 to maxfactor do
if sieve[i] then
begin
newp:=i+i;
while newp<=提maxp do
begin
sieve[newp]:=false;
newp:=newp+i;//每次取出这个数的倍数
end乡鲜易员技销矛安;
end;
评论留言