1.先介绍普通的算法,比较简单,直接贴代码
#include <iostream>
using namespace std;
const int MAX=100;
bool isPrime[MAX+1];
int total;//计数
int prime[MAX+1];
void makePrime1()
{
memset(isPrime, 1, sizeof(isPrime));
isPrime[0]=false;
isPrime[1]=false;
for (int i=2; i<=MAX; i++)
if (isPrime[i]) {
prime[total++]=i;
for (int k=i*i; k<=MAX; k+=i)
isPrime[k]=false;
}
}
2.线性筛选法
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,此处退出就可避免重复赋值。