百度空间 | 百度首页 
 
查看文章
 
[C语言学习札记]寻找10000以下的所有质数,并且计算其总和(更新为第2版)
2007年10月30日 星期二 下午 01:37

     昨晚(2007-10-29)在高校车协群里面讨论了中大11.3那个“业余自行车比赛”的安全问题后(部分链接在http://okbike.cn/bbs/viewthread.php?tid=8503&page=11&fromuid=2157#pid112929;希望真的千万不要出事),已经是(2007-10-30)凌晨2点了,然后无意间进了greysign的百度空间,看到一个monyer的黑客游戏(http://hi.baidu.com/greysign/blog/item/810a98267c8565148b82a145.html),想想最近压力很大,放松一下也好,就玩起来了。


     不过期间用了很多为人不齿的小聪明(实在太困,只为求快速过关),特别有一题求10000以内的质数,不想编程,就使用了自己最擅长的信息搜索和整理能力,外加Excel,10分钟搞定。不过走到第11关(asp session的问题)就不行了,建站毕竟自己没有接触,所以卡在那里,没往下做了,此时凌晨3点40分。

     早上醒来,觉得那题求10000以内的质数如果就只是依靠“信息搜索和整理”来完成,恐不是长久之计,而且,最近刚学过C语言的循环语句,因此,操刀DEV C++ 4.9.9.2,花了1个半小时终于编译通过了.......天啊,自己编程还是很差的说.......

     代码如下,欢迎指正。

     该段代码在DEV C++ 4.9.9.2下编译通过,Turbo C++ 3.0 IDE下编译失败。


#include <stdio.h>
#include <stdlib.h>

/*本程序演示寻找10000以下的所有质数,并且计算其总个数和总和(第1版)*/


int main(void)
{
   int row,x,temp,total,sum;      /*row为行计数控制数,x为除数,temp为除数,total为计算总质数个数,sum为所有质数的和*/
   row=1;total=1;sum=2;      /*众所周知,2为质数,所以就省略它的计算,直接从3开始*/
   printf("2 ");      /*显示2为质数*/
   for(x=3;x<10000;x++)      /*计算从3开始到100000内的质数*/
      {
              for(temp=2;temp<x;temp++)      /*除数从2开始到x*/
              {
                     if (x%temp==0)
                       break;      /*若x除以temp的余数为0,则不是质数,break跳出循环*/
                     else if(temp==x-1)      /*若temp已经达到x-1,则表示肯定是质数,开始计入质数*/
                       {
                             row=row+1;      /*现在该行有第row+1个质数显示出来*/
                             total=total+1;      /*现在共有total+1个质数*/
                             sum=sum+x;      /*质数相加*/
                             printf("%d ",x);      /*显示质数*/
                             if (row==10)      /*若该行有第10个质数,则回车并且row计数清空为10*/
                             {
                                   printf("\n");
                                   row=0;
                             }
                       }
                     else continue;       /*若什么都不是,继续循环(该句似乎没必要,没有也可正常运行,写上去只是为了维护if语句的完整性)*/
                }
      }
     
   printf("\nTotal find %d prime numbers,the sum is %d.\n",total,sum);       /*显示找到几个质数,并且求出结果*/
  
   system("PAUSE");          /*暂停以方便观察者察看输出结果*/
   return 0;
  
}

-------------分割线-------------

2007-11-15,19:25,第2版

如果把上面第1版的代码放到Turbo C 3.0编译,你会发现这种问题:

点击上图看大图,或者点击这里:
http://hiphotos.baidu.com/horseluke/pic/item/c2f38efba1a8e12e4f4aeab0.jpg

出现这种情况,是因为C语言中并没有具体规定各类数据所占内存的字节述,只要求数据长度long>=int,short<=int。具体如何实现,由各计算机系统自行决定。因此int在Turbo C定为16位,而DEV C++定为32位,所以出现这段代码在Dev C++编译通过但在Turbo编译失败的故障。

参考红栗(http://hi.baidu.com/redcornfield)在该页5楼写的JS代码,对该段代码做了优化,以减少计算工作量,和增加可移植性。欢迎各位指正。

该段代码在Turbo C++ 3.0 IDE和DEV C++ 4.9.9.2下编译通过。

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

/*本程序演示寻找10000以下的所有质数,并且计算其总个数和总和(第2版本,部分建议来自红栗及其JS代码)*/


int main(void)
{
int x,temp,total,flag;     /*x为待验证数(被除数),temp为除数,total为计算总质数个数,flag为标记*/
long sum;                /*sum为所有质数的和,因为对于sum来说,超过了32767,而有些编译器定义int为16位,为保持可移植性,必须改为long int值*/
total=1;sum=2;     /*众所周知,2为质数,所以就省略它的计算,直接从3开始,应此总质数格式total为1,所有质数的和sum为2*/
printf("2 ");     /*显示质数2*/
for(x=3;x<10000;x=x+2)     /*计算从3开始到100000内的质数;由于2的倍数肯定不是质数,所以加2跳过这些数*/
     {
             flag=1;     /*flag重置为1*/
             for(temp=2;temp<=sqrt(x);temp++)     /*除数从2开始到x的平方*/
                    if (x%temp==0)      /*若x除以temp的余数为0,则不是质数*/
                      {
                        flag=0;     /*flag标记为0,即不是质数*/
                        break;     /*结束本次循环,跳出*/
                      }
             if(flag==1)      /*检查flag标记,若为1(注意不能是flag=1,否则将出错)则表示此数为质数,开始计入;否则不计算*/
             {
                 total=total+1;     /*现在共有total+1个质数*/
                 sum=sum+x;     /*质数相加*/
                 printf("%d ",x);     /*显示该质数*/
                 if (total%10==0)     /*若该行有10个质数,则回车*/
                    printf("\n");

             }
     }
    
printf("\nTotal find %d prime numbers,the sum is %ld.\n",total,sum);      /*显示找到几个质数,并且求出结果(注意,第2个不能为%d而是%ld,因为前面定义为long int,否则在Turbo C溢出)*/

system("PAUSE");         /*暂停以方便观察者察看输出结果*/
return 0;

}


类别:关于电脑(c语言及电脑病毒) | 添加到搜藏 | 浏览() | 评论 (6)
 
最近读者:
 
网友评论:
2
2007年10月30日 星期二 下午 06:08 | 回复
汗,打错字了: x应该为待验证数(被除数)。
 
3
2007年10月30日 星期二 下午 07:55 | 回复
1除到temp<=sqrt(x)就可以了 2换行if(total%10==0) printf("\n"); 3可以用++ +=运算 4空的else和空的then是一种冗余 5这点好长,唔愿打,慢慢来吧
 
4
2007年11月01日 星期四 下午 04:54 | 回复
其实也不算什么指正,只是一些优化的建议。完成同样的功能,当然是时间开销越少,代码越简洁越好啦。我也开始接触C了,没有教材,很难学…
 
6
2007年11月30日 星期五 上午 11:12 | 回复
main() { int i,n,flag; long int sum; sum=2; for(n=3;n<=10000;n++) { flag=1; for(i=2;i<=n-1;i++) { if ((n % i)==0) { flag=0; break; } } if (flag==1) { //printf("%d\n",i); sum=sum+i; } } printf("%ld",sum); } 这个在turboC下通过。 使用long int时候,就可以避免int的溢出啦! 当然,这个for(i=2;i<=n-1;i++)的n-1可以使用sqrt(n),记住前面要添加include
 
7
2007年11月30日 星期五 上午 11:18 | 回复
呵呵。和你思路一致,哈哈,刚才没看你呢。 不过自己思考了一遍,还是有所收获呢!
 
8
2008年01月04日 星期五 下午 12:31 | 回复
很好,加油
 
发表评论:
姓 名:
网址或邮箱: (选填)
内 容:
验证码: 请点击后输入四位验证码,字母不区分大小写
      

     

©2009 Baidu