线性筛选
时间复杂度O(n)
数学原理
对于一个合数N = P * M
1、P是最小素数
2、P一定小于等于M的最小素因数
3、用M * P 标记合数
代码
int prime[1000];
void Inil(){
for (int i = 2; i <= 1000; i++){
if (!prime[i]) prime[++prime[0]] = i; //记录素数,其中prime[0]是计数器
for (int j =1; j <= prime[0]; j++){
if (i * prime[j] > 1000) break;
prime[prime[j] * i] = 1; //标记为合数
if (i % prime[j] == 0) break; //p不能大于M的最小素因数
}
}
return;
}
举个例子:
4 * 2 = 8,接下来4*3 =12可以执行吗? 不能!因为4 = 2 *2, 3比2大,12 = 6 2 ;
8 * 2 = 16,接下来的8 * 3 = 24可以执行吗? 不能,因为8 = 4 * 2,3大于2,24=12 * 2
即所有的合数虽然会被标记,但是如果用素数筛会被标记很多次
但是线性筛的原理就是每一个合数,都只会被两个素数的乘积标记,或者一个素数a一个合数b的乘积标记,且这个a 小于等于 b的最小素约数,例如3 > 2 (8 = 2 * 4),即24就不能用 38标记,应该用12 * 2标记。
在算法上,就是当i % prime[j] == 0直接跳出循环即可。