素筛法——用空间复杂度换取时间复杂度的高效算法
1、素数
要讲素筛法,我们首先得谈谈什么是素数。
素数(或质数)是指在大于1的自然数中,除了1和它本身以外不再有其他因数的自然数。
因而,基于它的定义,我们可以推出以下结论:
(1)、1都不是素数,因为1不是大于1的自然数。
(2)、2是素数,因为2只有1和2两个因数,也即2只能被1、2两个数整除。
(3)、大于2的偶数一定不是素数,因为它除了有1和它本身两个因数外,还一定有2这个因数。
(4)、因为大于2的偶数一定不是素数,所以大于2的素数的一定是奇数。
(5)、素数的倍数一定不是素数,因为若设这个素数的倍数所构成的数为n,倍数为k,则对于数n,其除了有1和n的两个因数外,还有因数k。
2、素数筛选法——素筛法
除了以上的结论外,我们还得知道:
(6)、一个数n除了它本身外的可能的最大因数为⌊√n ⌋
(PS:为了打出"√"这个符号,可左手按住Alt换挡键不放,右手输入代码41420)
有了以上的理论储备后,便可以设计出以下代码:
#include<iostream>
using namespace std;
int prime[1000000];
void caculatePrime(){
prime[0] = prime[1] = 1;
for(int i = 2; i*i <= 1000000; i++){
if(!prime[i]){
for(int j = i*i;j <= 1000000; j += i){
prime[j] = 1;
}
}
}
}
int main(){
caculatePrime();
int n;
cin >> n;
for(int i = 1;i <= n; i++){
if(!prime[i])
cout << i << endl;
}
}
用一个全局变量的数组prime存储1-1000000内的素数,prime[i]=0则表明i为素数,prime[i]=1则表明i不为素数。