素数的唯一性定理与求1到100之间所有素数的问题

bluescorpion 2012-04-04 12:22:49
求1到100之间的所有素数的问题。
如果一个数是素数,姑且叫这个数为P好了,那么P是不可能被1到P之间除1和P外的任何一个其他的素数整除。那么有如下算法:­

算法1

int GetPrimeFromOne2Hundred()
{
int p[30]={0};
int i,j;
int count1=0,count2=0;//用于累计循环次数

for(i=1;i<=100;i++)
{
j=0;
while(p[j]!=0&&(p[j]==1||i%p[j]!=0))
{
j++;
count1++;
}
if(p[j]==0)
{
p[j]=i;
count2++;
}
}

for(i=0;i<30;i++)
printf("%d\t",p[i]);

printf("%d\t%d\t%d\t",count1,count2,count1+count2);//输出循环次数

return 0;
}

count1的值为436,count2的值为26,总共为462次。

其实对于一个整数N,将其分解成两个因数,任一一个因数的减小都会造成另外一个因数的增大。假设N=i*j,i和j都是整数,那么N%i与N%j都是等于0,在这个问题中二者的意义是一样的。于是我们可以找到一个数m,即只要N不能被小于m的整数整除的话,那么就可以断定N是素数,这个数既是m=(int)sqrt(N),根据“素数的唯一性定理”,范围还可以缩小,只要N不能被小于m的素数整除的话,那么就可以断定N是素数。于是该算法可改进如下:­
算法2

int GetPrimeFromOne2Hundred()
{
int p[30]={0};
int i,j,k,n;
int count1=0,count2=0;//用于累计循环次数

n=0;

for(i=1;i<=100;i++)
{
j=0;
k=(int)sqrt((double)i);
while(p[j]!=0&&p[j]<=k&&(p[j]==1||i%p[j]!=0))
{
j++;
count1++;
}

if(p[j]==0||p[j]>k)
{
p[n]=i;
n++;
count2++;
}

}
for(i=0;i<30;i++)
printf("%d\t",p[i]);

printf("%d\t%d\t%d\t",count1,count2,count1+count2);//输出循环次数

return 0;
}

count1的值为206,count2的值为26,总共为232次。

循环总次数,与算法1相比,算法2减少230次。但随着范围的扩大,例如求1到1000之间的素数,则对于算法1,循环总次数为15788+169=15957次;而对于算法2,循环总次数为2969+169=3138次。可见算法2相对算法1,效率有很大提高。
...全文
279 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

695

社区成员

发帖
与我相关
我的任务
社区描述
提出问题
其他 技术论坛(原bbs)
社区管理员
  • community_281
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧