求1亿内素数个数的C++程序 详细解释

这篇博客详细解析了求1亿内素数个数的C++程序,通过位集(bitset)实现空间换时间的优化。文章探讨了为何程序中包含if(p->test(i))条件判断,以及如何证明通过遍历2-9999的倍数即可囊括1亿内所有合数,避免了重复遍历。作者通过逐步分析证明了该方法的正确性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

钱能的C++教程上,有一段求1亿内素数的个数的程序,之前理解得不透,今天才稍微往深了理解了一些。


一般的思路就不说了,效率低得很。书里介绍了一种用空间换时间的方法:即用二进制中的一位代表数字。显然需要1亿位,可以用int型中的位,也可以用位集bitset。


书中有这样一段程序:


for(int i=2;i<=10000;i++)
  if(p->test(i))
    for(int j=i*i;j<p-size();j+=i)
        p-reset(j);


单看这段程序,尝试了2到10000的所有素数的小于1亿的倍数,然后将位集中的相应位设为0,将其排除。


以前看到的时候,主要有两个疑问:
1.为什么有if(p->test(i))这个条件判断?
2.1万内所有数的倍数能否囊括掉1亿内的所有合数?


凡事就怕琢磨,一琢磨就能发现其实里面值得思考的地方还是挺多的。假设集合A:2-9999的小于1亿的所有倍数;集合B:1亿内所有的合数(不包括1亿)。看看这两个集合是否相等。
在证明之前,我先解释一下为什么考察的是2-9999的倍数,因为毕竟程序中尝试了2-10000的素数。其实,“2-9999的小于1亿的所有倍数”和“2-10000的小于1亿的所有倍数”是同一个集合。10000的小于1亿的倍数被包括在了2-9999的倍数中。


证明:对于集合A中的每一个元素,肯定属于集合B,故B>=A;
      对于集合B中的每一个元素,都有一个小于1万的因子,即B中的元素n=x*y,x小于1万。故也属于集      合A,所以A>=B;
      综上,A=B。
所以,我们原来的思路是:剔除掉1亿内的所有合数。现在,我们转换思路:剔除掉2-9999的所有小
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值