素数定义
除了自身与1之外没有其他因数
例子
输入一个数字n,求出n以内包括n的所有素数
- 常规筛
时间复杂度O(n*sqrt(n))
#include <stdio.h>
int isPrime(int num){
for(int i=2; i*i<=num; i++)
if(num%i==0){return 0; break;}
return 1;
}
int main(){
int n;
scanf("%d",&n);
for(int i=2; i<=n; i++)
if(isPrime(i)) printf("%d\n",i);
return 0;
}
- 埃氏筛
思路:
时间复杂度O(nloglogn),首先,2是公认最小的质数,所以,先把所有2的倍数去掉;然后剩下的那些大于2的数里面,最小的是3,所以3也是质数;然后把所有3的倍数都去掉,剩下的那些大于3的数里面,最小的是5,所以5也是质数…
上述过程不断重复,就可以把某个范围内的合数全都除去(就像被筛子筛掉一样),剩下的就是质数了。
#include <stdio.h>
int main(){
int n;
scanf("%d",&n);
int isPrime[n+1];
for(int i=0; i<n+1; i++) isPrime[i]=1;
isPrime[0]=isPrime[1]=0;
for(int i=2; i<=n; i++){
if(isPrime[i]){
printf("%d\n",i);
for(int j=2; i*j<=n; j++) isPrime[i*j]=0;
}
}
return 0;
}
- 欧拉筛
思路:
时间复杂度为O(n)。与埃氏筛相比,不会对已经被标记过的合数再进行重复筛,故效率更高。欧拉筛保证合数仅被该合数的最小值因数筛去仅一次。
#include<stdio.h>
#include<stdbool.h>
int main(void){
int n,count=0;
scanf("%d",&n);
bool number[n+1];
int prime[n+1];
memset(number,true,sizeof(number));
for(int i=2;i<=n;i++){
if(number[i]) prime[count++]=i;
for(int j=0;j<count&&prime[j]*i<=n;j++){
number[prime[j]*i]=false;
if(i%prime[j]==0) break;
}
}
for(int i=2;i<n+1;i++)
if(number[i]==true) printf("%d\n",i);
return 0;
}
关键在于理解第13行的if(i%prime[j]==0) break;
,该行保证了每一个合数只被它的最小质因数筛一次。
例如当i%prime[j]==0
时,则i*prime[j+1]
一定是prime[j]
的整数倍,因为i
可以整除prime[j]
,并且i*prime[j+1]/prime[j]>i
所以在当前i
中,i*prime[j+1]
还不能被筛,因为当前的i
无法使得i*prime[j+1]/prime[j]
等于i*prime[j+1]
的最小质因数。举个例子:当i=8
,prime
数组中有{2,3,5,7}
,此时计算i*prime[j],0<=j<4
,结果为{16,24,40,56}
,此时16除以8等于2,2是16的最小质因数,所以16被筛去;但此时24除以8等于3,3不是24的最小质因数,所以此时24不能被筛去,因为24应该被2筛去,而24除以2等于12,所以24应该在i=12的时候被筛去,40与56同理。综上,当if(i%prime[j]==0)
时,跳出循环。
打印出当n=100时的运行过程帮助理解:
4被2筛去,此时i=2
6被2筛去,此时i=3
9被3筛去,此时i=3
8被2筛去,此时i=4
10被2筛去,此时i=5
15被3筛去,此时i=5
25被5筛去,此时i=5
12被2筛去,此时i=6
14被2筛去,此时i=7
21被3筛去,此时i=7
35被5筛去,此时i=7
49被7筛去,此时i=7
16被2筛去,此时i=8
18被2筛去,此时i=9
27被3筛去,此时i=9
20被2筛去,此时i=10
22被2筛去,此时i=11
33被3筛去,此时i=11
55被5筛去,此时i=11
77被7筛去,此时i=11
24被2筛去,此时i=12
26被2筛去,此时i=13
39被3筛去,此时i=13
65被5筛去,此时i=13
91被7筛去,此时i=13
28被2筛去,此时i=14
30被2筛去,此时i=15
45被3筛去,此时i=15
32被2筛去,此时i=16
34被2筛去,此时i=17
51被3筛去,此时i=17
85被5筛去,此时i=17
36被2筛去,此时i=18
38被2筛去,此时i=19
57被3筛去,此时i=19
95被5筛去,此时i=19
40被2筛去,此时i=20
42被2筛去,此时i=21
63被3筛去,此时i=21
44被2筛去,此时i=22
46被2筛去,此时i=23
69被3筛去,此时i=23
48被2筛去,此时i=24
50被2筛去,此时i=25
75被3筛去,此时i=25
52被2筛去,此时i=26
54被2筛去,此时i=27
81被3筛去,此时i=27
56被2筛去,此时i=28
58被2筛去,此时i=29
87被3筛去,此时i=29
60被2筛去,此时i=30
62被2筛去,此时i=31
93被3筛去,此时i=31
64被2筛去,此时i=32
66被2筛去,此时i=33
99被3筛去,此时i=33
68被2筛去,此时i=34
70被2筛去,此时i=35
72被2筛去,此时i=36
74被2筛去,此时i=37
76被2筛去,此时i=38
78被2筛去,此时i=39
80被2筛去,此时i=40
82被2筛去,此时i=41
84被2筛去,此时i=42
86被2筛去,此时i=43
88被2筛去,此时i=44
90被2筛去,此时i=45
92被2筛去,此时i=46
94被2筛去,此时i=47
96被2筛去,此时i=48
98被2筛去,此时i=49
100被2筛去,此时i=50