筛出1~n之间的所有质数.
Eratosthenes筛法,即找到一个质数x后,把x的倍数2x,3x...(n/x)*x都标记为质数.当扫描到一个数时,若没有被标记过就说明它是质数,反之不是质数.大致过程如下:
2, | 3, | 5, | 7, | 9, | 11, | 13, | ... | ||||||
2, | 3, | 5, | 7, | 11, | 13, | ... | |||||||
2, | 3, | 5, | 7, | 11, | 13, | ... | |||||||
2, | 3, | 5, | 7, | 11, | 13, | ... | |||||||
2, | 3, | 5, | 7, | 11, | 13, | ... | |||||||
2, | 3, | 5, | 7, | 11, | 13, | ... |
于是就有了代码:
#include <iostream>
#define maxn 10000 + 5
using namespace std;
bool prime[maxn];
int n;
void primes(const int &n){
for(int i = 2; i <= n; i++) if(!prime[i]){//如果是质数
cout << i << " ";
for(int j = 2 * i; j <= n; j += i)//i是质数,不对其进行操作
prime[j] = true;
}
}
int main(){
cin >> n;
primes(n);
return 0;
}
不过仔细观察上面的表格,会发现2和3都对6进行了更新.所以我们可以进行优化,第二层循环的下限改成x²,把x²,(x+1)*x,...,(n/x)*x标记就可以了.优化后如下:
#include <iostream>
#define maxn 10000 + 5
using namespace std;
bool prime[maxn];
int n;
void primes(const int &n){
for(int i = 2; i <= n; i++) if(!prime[i]){
cout << i << " ";
for(int j = i; j <= n / i; j++)
prime[i * j] = true;//设循环次数为k,则第k次循环中j表示(i+k).
}
}
int main(){
cin >> n;
primes(n);
return 0;
}
时间复杂度为O(NloglogN).美滋滋~