钱能的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的所有小
一般的思路就不说了,效率低得很。书里介绍了一种用空间换时间的方法:即用二进制中的一位代表数字。显然需要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的所有小