C语言书上的一个例题看不懂

题目是用筛选法输出100以内的素数

#include<iostream>
#include<math.h>

int main(){
int i,j,n,a[101];
for(i=1;i<=100;i++)
a[i]=i;
a[1]=0;//1不是素数
for(i=2;i<sqrt(100.0);i++)//此处为求素数算法,后面讲
for(j=i+1;j<=100;j++)
{
if(a[i]!=0&&a[j]!=0)
if(a[j]%a[i]==0)//能被整除,则不是素数,设置为0
a[j]=0;
}
printf("\n");
for(i=2,n=0;i<=100;i++)
{
if(a[i]!=0)//这里是a[i],是因为已经是新的循环了,跟j无关
{
printf("%5d",a[i]);
n++;
}
if(n==10)//n为控制换行的计数器,每十个换行。
{
printf("\n");
n=0;
}
}
printf("\n");
system("pause");
return 0;
}

讲一下求素数的算法,以n为例,最简单的是从2-n/2枚举,如果n能被整除其中一个整除,就不是素数。这个方法简单却没有效率。

1-100的数中,任意取一个数,如果是非素数,都可以认为是(2-10)取一个数乘以一个小于50的数字,因为>=10 后,与另一个数字相乘要<=100 就必须另一个数字<=10,所以只要测试这个数字能否被2-10整除就可以了这样就比上面一种方法测试次数少。

当然这也不是最简单的算法,这里介绍另一种。

for(i=3;i<=100;i++)
if(i%2==0)//没必要判断2以外的偶数
a[i]=0;
else
a[i]=i;
a[1]=0;
a[2]=2;
for(i=3;i<=100;i+=2)//从3开始,判断奇数即可
for(j=3;j<=sqrt(i);j+=2)
//因为不用检测偶数,所以没必要让j从2开始,也没必要为偶数,因此j+=2
if(i%j==0)
a[i]=0;

这算法和上面方法相同,但反了一反,效果却差很多,不必从2-10都测试一遍,任意一个数都只要判断自己的平方根次就可以了,(因为一个数若能拆成2个整数相乘,其中一个必定<=自身平方根,另一个>=平方根),不必去测试额外的次数,对于大数据量十分有效。


编程的时候把缩进调整好,容易查看,你的缩进不好,程序结构层次不清,就容易造成误会,把后面的a[i]认为仍然是 for(j=i+1;j<=100;j++)这个循环中了

温馨提示:答案为网友推荐,仅供参考
第1个回答  2013-07-20
这个程序写得不是很清楚啊。。个人觉得for循环语句的内容还是加个花括号比较好,这段代码缩进也不对,看得好辛苦。。感觉你对for循环和变量不是很熟悉,建议还是多看一下书吧。
我改了一下,你看一下,不懂再问我吧。打得好辛苦,请采纳好评~~

# include<stdio.h>
#include<iostream>
#include<math.h>
using namespace std;
int main()
{
int i,j,n,a[101];
for(i=1;i<=100;i++)
a[i]=i;
a[1]=0;
double t=100;
for(i=2;i<sqrt(t);i++) //第一个地方,a<sqrt(100), 就是a<10, 因为一个合数,除1之外,最小的因数一定小于或等于自身的开方。
{
for(j=i+1;j<=100;j++) //你理解错了,j的范围为i+1到100.i的范围为2到9.
{
if(a[i]!=0&&a[j]!=0) //先判断两者中是否存在已经判断不是质数(即已赋值为0),如果已为合数,则不用判断了,结束循环。
if(a[j]%a[i]==0) //如果仍未判断,则考虑较小那个数能否被另一个数整除。如果能,则将a[j]为合数,赋值为0。
a[j]=0;
}
} //注意第一个for循环到这里结束
printf("\n");
for(i=2,n=0;i<=100;i++) //这里是输出所以质数,i和j都是全局变量来的,在这个循环里已经把i的值改变了。i的值为2到100.
{ if(a[i]!=0)
{
printf("%5d",a[i]);
n++;
}
if(n==10) //使输出结果每行10个
{
printf("\n");
n=0;
}
}
printf("\n");
return 0;
}本回答被提问者和网友采纳
第2个回答  2013-07-20
可以单步调试学习吧,错误十分明显。
看不懂可以画个流程图,然后思考一下一个数在这个流程图中走,变化怎样,变化是否正常追答

如果有需要,我可以把筛选法的思想告诉你,其实蛮简单的。一秒能解决的数据绝对不止100

第3个回答  2013-07-20
一步一步来啊 ,把不懂的那句注释掉,再看看,培养纠错能力。不要动不动就让别人找错误。我虽然知道问题出在哪里,但我决定不告诉你。你再看看吧 ,很明显
第4个回答  2013-07-20
1步1 步调试运行。