一:埃拉托斯特尼筛法(Sieve of Eratosthenes)
1.算法的基本思想:
如果一个数是质数,那么它的倍数肯定非质,利用事先定义的线性表以打表方式标记非质,则剩下的数就是素数。
2.筛选过程:
//#include <bits/stdc++.h> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <iostream> #include <algorithm> #include <iostream> #include <cstdio> #include <string> #include <cstring> #include <stdio.h> #include <queue> #include <stack>; #include <map> #include <set> #include <ctype.h> #include <string.h> #include <vector> #define ME(x , y) memset(x , y , sizeof(x)) #define SF(n) scanf("%d" , &n) #define rep(i , n) for(int i = 0 ; i < n ; i ++) #define INF 0x3f3f3f3f #define PI acos(-1) using namespace std; typedef long long ll ; const int mod = 1e9+7 ; const int N = 100009 ; int vis[N]; int a[N];//素数表 int main() { vis[1] = 0 ; for(int i = 2 ; i <= N ; i++)//都标记为素数 vis[i] = 1 ; int m = floor(sqrt(N)+0.5) ; for(int i = 2 ; i <= m ; i++) { if(vis[i]) { for(int j = i * i ; j <= N ; j += i) { vis[j] = 0 ;//利用素数的倍数是合数筛选 } } } int l = 0 ; for(int i = 1 ; i <= N ; i++) { if(vis[i]) { a[l++] = i ; cout << i << endl ; } } return 0; }
总结:Eratosthenes筛选法虽然效率高,但是Eratosthenes筛选法做了许多无用功,一个数会被筛到好几次,最后的时间复杂度是O(nloglogn),对于普通素数算法而言已经非常高效了,但欧拉筛选法的时间复杂度仅仅为O(n).
二:欧拉筛选法
1.算法的基本思想:
prime数组 中的素数是递增的,当 i 能整除 prime[j],那么 i*prime[j+1] 这个合数肯定被 prime[j] 乘以某个数筛掉。
因为i中含有prime[j], prime[j] 比 prime[j+1] 小。接下去的素数同理。所以不用筛下去了。
在满足i%prme[j]==0这个条件之前以及第一次满足改条件时,prime[j]必定是prime[j]*i的最小质因子。
//#include <bits/stdc++.h> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <iostream> #include <algorithm> #include <iostream> #include <cstdio> #include <string> #include <cstring> #include <stdio.h> #include <queue> #include <stack>; #include <map> #include <set> #include <ctype.h> #include <string.h> #include <vector> #define ME(x , y) memset(x , y , sizeof(x)) #define SF(n) scanf("%d" , &n) #define rep(i , n) for(int i = 0 ; i < n ; i ++) #define INF 0x3f3f3f3f #define PI acos(-1) using namespace std; typedef long long ll ; const int mod = 1e9+7 ; const int N = 100009 ; int vis[N]; int a[N];//素数表 int main() { vis[1] = 0 ; for(int i = 2 ; i <= N ; i++)//都标记为素数 vis[i] = 1 ; int l = 0 ; for(int i = 2 ; i <= N ; i++) { if(vis[i]) { a[l++] = i ; } for(int j = 0 ; j < l && i * a[j] <= N ; j++) { vis[a[j]*i] = 0 ; if(i % a[j] == 0) break ;//每一个合数都将被其最小质因数筛去 } } for(int i = 0 ; i < l ; i++) cout << a[i] << endl; return 0; }