Chinaunix首页 | 论坛 | 博客
  • 博客访问: 444378
  • 博文数量: 78
  • 博客积分: 2307
  • 博客等级: 上尉
  • 技术积分: 920
  • 用 户 组: 普通用户
  • 注册时间: 2011-06-04 00:31
个人简介

IT老鸟,信息安全硕士。

文章分类
文章存档

2017年(2)

2012年(21)

2011年(55)

分类: C/C++

2011-06-20 14:11:59

在半年前我写了个质数的筛法。测试时间复杂度是3.3*n而实际上老师的筛法是1.8倍的N当时他的算法我没看懂,老师过多的使用了乘法。而实际上乘法的效率是很低的。今天看懂了。

我室友写了个筛法。

这个是我们之前写的地址

 

我和老师的代码都是冗余在第三层。使用常规筛法如果3的倍数干掉那么3*7*5的值是倍干掉的。但是到了5这里5*3*7又被干掉了一次。这样就造成了冗余。而实际上我是在做乘法的时候只是如果15(被干掉)

我的筛法也有这方面的因素。我的筛的冗余实在第三层。是相邻的比较。相邻的比较是N*N的复杂度固有的特征。如果第三层的是false那么就不去乘以。就继续。这样还是有冗余。去掉的最好方式就是不存在。我的代码第三层如果使用链表解决应该时间复杂度趋近于这个数值。下次测试一下。

  1. # include<stdio.h>
  2. # include<math.h>
  3. # define N 200000000
  4. bool prime[N+1];
  5. int main()
  6. { int i,j;
  7. long ljq=0; //记录筛选的次数 当时写成了累加器的缩写.大家更喜欢用count
  8. int cout=1; //记录质数的个数 2走后门, 故初值应设为一
  9. int m=0;//记录i的值,为循环变量的辅助变量
  10. for(i=3;i<=N;i=i+2)//所有的偶数全部干掉
  11. prime[i]=true;
  12. for(i=3;i<=sqrt((N-1));i=i+2)//第一层取平方数
  13. {
  14.     //printf("i=%d/n",i);
  15.      m=i;
  16.      ljq++;
  17.     if(prime[i]==true)
  18.            
  19.         for(j=i*i;j<=N;j=i*m)//筛法的第二层。从平方开始如果是存在的就筛掉
  20.         {
  21.                 m=m+2;
  22.             if(prime[j]==true)
  23.             {
  24.                 prime[j]=false;
  25.         // printf("%d/t",j);//测试用例。用于查看筛掉的数
  26.             }
  27.         }//第二层结束
  28. //printf( "/n");//测试用例。用于分割筛掉的数。分割间的数之间有相同的差
  29.   
  30.     }//第一层结束
  31.   
  32. //printf("/n");
  33.   
  34. printf("%d/t",2); /*2非奇数故未在循环算法之内,但2是素数,故先输出*/
  35. //打印质数
  36. for(i=3;i<=N;i=i+2)
  37. if(prime[i]==true)
  38. {
  39. printf("%d/t",i);
  40. cout++;
  41. }
  42. printf("/n");
  43. printf("步长%d",ljq);
  44. printf("/n");
  45. printf("质数的个数%d",cout);
  46.   
  47. return 0;
  48. }

计算的是2亿的步长196457228两亿的6秒钟。比老师的快了一秒。

不包括打印时间。

时间复杂度不详,筛法的复杂度是Nlog(logN)实际上不到.

阅读(4884) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~