华师一附中OI组

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 1961|回复: 1
打印 上一主题 下一主题

筛法求质数

[复制链接]

738

主题

1485

帖子

5422

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
5422
跳转到指定楼层
楼主
发表于 2019-1-6 20:15:17 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
筛法求质数的流程:假设求2-100之间的所有质数
1、把2-100之间的所有数写在纸上。(对应编程的做法就是a数组中a(2)-a(100)全部设为1)
2、从2到100,若这个数是质数,那么把它的2倍,3倍,直到不超过100的所有倍数全部刷掉;若不是,则直接跳到下一个数。           用i表是这个数,则刷掉它的倍数可以用类似开关灯的方法来做,两种写法。
3、检查纸上的数字若没有被刷掉,表示是质数,则输出(对应编程的做法就是检查a(2)-a(100),若为1则输出对应的下标)
把上面的解释转换成程序:
1、for (i=2;i<=100;i++) a(i)=1;
2、for (j=i+i;j<=100;j++) a(j)=0;或者for (j=i+1;j<=100;j++) if (j%i==0) a[j]=0;   显然第一种更好。
3、for (i=2;i<=100;i++) if (a(i)==1) cout<<j<<' ';


合成为完整的程序:

  1. #include <iostream>
  2. using namespace std;
  3. const int mn=100;
  4. bool a[mn+5];
  5. int i,j;
  6. int main()
  7. {
  8.         for (i=2; i<=mn; i++) a[i]=1;
  9.         for (i=2; i<=mn; i++)
  10.                 if (a[i]==1)  for (j=i*2; j<=mn; j+=i) a[j]=0;
  11.         for (i=2; i<=mn; i++) if (a[i]==1) cout<<i<<' ';
  12.         return 0;
  13. }
复制代码


回复

使用道具 举报

738

主题

1485

帖子

5422

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
5422
沙发
 楼主| 发表于 2020-2-11 14:51:26 | 只看该作者
象楼上那样做是比较简单清晰的,效率还可以提高,
1、j没有必要从i*2开始,因为i*2可能已经被2刷掉了,i*3可能已经被3刷掉了
2、i的终点没有必要到mn,后面的一些其实早就被刷掉了两者的共同理由是若x=a*b,则x肯定先被a和b中较小数刷掉,那么第一个问题中的j只需要从i*i开始就可以了,第二个问题中的i只需要到sqrt(i)就可以了。

  1. #include <iostream>
  2. using namespace std;
  3. const int mn=100;
  4. bool a[mn+5];
  5. int i,j;
  6. int main()
  7. {
  8.         for (i=2; i<=mn; i++) a[i]=1;
  9.         for (i=2; i*i<=mn; i++) ///i<=sqrt(mn)
  10.                 if (a[i]==1)  for (j=i*i; j<=mn; j+=i) a[j]=0;
  11.         for (i=2; i<=mn; i++) if (a[i]==1) cout<<i<<' ';
  12.         return 0;
  13. }
复制代码


回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|服务支持:DZ动力|华师一附中OI组  

GMT+8, 2024-12-26 15:23 , Processed in 0.099909 second(s), 22 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表