arr[]初始化为1,合数标记为0
1.从素数的概念直接得到的求解算法
void prime_solve(int arr[], int n)
{
for(int i=3;i<=n;i++)
{
for(int j=2;j<i;j++)
{
if(i%j == 0)
{
arr[i]=0;
break;
}
}
}
2.算法1的优化分析——对判定数的执行步骤的优化
对于n以内的合数来讲,上述算法只要找到最小的约数,试除结束;而对于质数i,则需要试除到i-1才能确定其是否为质数。
优化思路:在保证合数的最小约数被找到的前提下,减少试除次数。
假定合数A=B*C,其中B是A的最小约数,则B<=C,B^2<=A
可以得出,若A为合数,其最小约数应小于等于A的开方。
void prime_solve_opt1(int arr[], int n)
{
for(int i=3;i<=n;i++)
{
for(int j=2;j*j<=i;j++)
{
if(i%j == 0)
{
arr[i]=0;
break;
}
}
}
}
3.算法1的优化分析——判定数的选择
当确定一个素数之后,可以排除它的倍数为合数,所以不必对所有的数都做一次判断。
要确定的是,对于合数i,在得到哪个素数的时候可以被筛掉。
同样假定合数A=B*C,其中B是A的最小约数,则B<=C,B^2<=A,当B被确定的时候,A可被筛掉。
可以得出,只需要判定到根号A的数,就可以将A以内的合数筛掉。
void prime_solve_opt2(int arr[], int n)
{
for(int i=3;i*i<=n;i++)
{
if(arr[i]==0)
continue;
for(int j=2;i*j<=n;j++)
{
arr[i*j]=0;
}
}
}
4.算法3的优化分析
在进行合数筛除的过程中,合数可能被筛除多次,若能够保证每个合数被筛除一次能进一步优化算法。
对于一个合数A=p1* p2 * … pn,若用p2 … *pn去筛除,则只会被筛一次。
void prime_solve_opt3(int arr[], int n)
{
int plist[100], pcnt=0;
for(int i=2;i<=n;i++)
{
if(arr[i])
plist[pcnt++]=i;
for(int j=0;j<pcnt&&i*plist[j]<=n;j++)
{
arr[i*plist[j]]=0;
if(i%plist[j]==0)
break;
}
}
}
5.算法4的优化
偶数都不是素数,根据该性质对所有的偶数都不做判断,主动筛除。
详见http://blog.csdn.net/dinosoft/article/details/5829550