.线性筛选法
算法中的一个难点是:if(i%prime[j]==0) break;下面做下解释:
先举个例: 4*3=12=6*2;如果没有上面那行代码,则在i=4时,isPrime[12]=false;
在i=6时,isPrime[12]=false;这个句子会执行两次,从而导致重复执行降低了效率。使用上面那行代码进行判断后则可以避免。
1)原理:
i. 任何一个合数都可以表示成一个质数和一个数的乘积
ii. 假设A是一个合数,且A = x * y,这里x也是一个合数,那么有:
A = x * y; (假设y质数,x合数)
x = a * b; (假设a是质数,且a < x)
=》 A = a * b * y = a * Z (Z = b * y)
即一个合数(x)与一个质数(y)的乘积可以表示成一个更大的合数(Z)与一个更小的质数(a)的乘积
2)代码:
- void makePrime2()
- {
- memset(isPrime,true,sizeof(isPrime));
- memset(prime,0,sizeof(prime));
- for(int i=2;i<=MAX;i++)
- {
- if(isPrime[i]) prime[total++]=i;
- for(int j=0; j<total && i*prime[j]<=MAX; j++)
- {
- isPrime[i*prime[j]]=false;
- if(i%prime[j]==0) break;
- }
- }
- }
算法中的一个难点是:if(i%prime[j]==0) break;下面做下解释:
先举个例: 4*3=12=6*2;如果没有上面那行代码,则在i=4时,isPrime[12]=false;
在i=6时,isPrime[12]=false;这个句子会执行两次,从而导致重复执行降低了效率。使用上面那行代码进行判断后则可以避免。
注意一个合数和一个质数的乘积可用一个更大的合数和一个更小的质数的乘积表示,如 12=4×3=2×2×3=6×2;4%2=0就表示可以用更大的合数表示4×3,此处退出就可避免重复赋值。
用了每个合数必有一个最小素因子,每个合数肯定能够由素数的相乘得到。
每个合数仅被它的最小素因子筛去正好一次。所以为线性时间。