简单算法之素数筛法

来源:互联网 发布:云计算java工程师招聘 编辑:程序博客网 时间:2024/05/16 19:25

素数在数学问题中应该是比较常见的,那么我们如何去将一个大范围的区间内的数进行筛选打表呢?
下面我就简单说说几个常见的算法。
下面的都以1000以内的数为例(我的代码都是先判断再打印,直接打印出存储素数的数组也可以)

最基础的算法

这里写图片描述

我们显然可以看到每判断一个数需要从2到这个数全部跑一边,时间复杂度太高。可以进行小小的优化,把j < i改成j <= sqrt(i) 因为如果一个数开方取整都没有因数的话,其他比它小的就必然不是其因数了,所以只需要到开方处的数即可。
但这样去处理大范围的数的话复杂度还是太高。下面再介绍两种比这复杂度大大降低的算法。

埃拉托斯特尼算法

我们首先由2开始,2是最小的素数,那么2的倍数则肯定不是素数,将这些数从里面踢掉即可,也就是panduan[i] = 0,筛完后剩下的
下一个数就是3了,同理将3的倍数的数踢掉,以此类推。这样算法的时间复杂度比刚刚的基本算法大大降低了。下面是我写的打表代码。

这里写图片描述

注意到我在筛掉倍数的时候是从i*i开始的,因为i*2或i*3之类的可以被2和3等比i更小的数分别筛掉,无需重复操作。比如30 被2,5,6等重复筛掉了,增加了复杂度。
但其实这其中还是有多余的操作的,比如36 被4*9筛掉了,又被2*18筛掉了,所以可见这并不是最优的算法。
将这个问题比较好地解决了的是下面的欧拉算法。

欧拉算法

在进行欧拉算法之前,我们需要明白一点。所有合数(即除了1和本身外还有其他因数)都可以表示为一系列素数的乘积,且这些素数唯一。(证明过程在最底下)
要去解决上面的问题,欧拉算法中保证了每个筛去的数均由一系列乘积组成它的素数中最小的那个素数筛去,这样算法的复杂度就是线性的了O(n)。以下是代码。
这里写图片描述

这里写图片描述
为什么称其为精华呢,因为当 i 可以整除 su[j] 的时候,i 中就包含了 su[j],比i * su[j]更大的乘积一定可以用su[j]乘以一个更大的数来表示,无需重复筛去了。
这样就比之前降低了许多复杂度。这个算法是不是很厉害呢。下面顺便附上输出来的结果。
这里写图片描述

掌握了这些,在素数方面应该就没有什么大问题啦。希望读者看了能够有所收获,早日成为算法大神!(上面几个定理的证明在下面)

证明过程:

因为下面需要用到裴蜀定理,所以我先证明一下裴蜀定理。
裴蜀定理简单点来说就是假如d是a,b的最大公约数,一定存在整数x,y,使ax+by=d成立。
下证:因为d是a,b的最大公约数,所以p|a,p|b(表示p可以整除a与b)
,所以有d|(ax+by)。设s为ax+by最小正值,所以必然有d|s
这里写图片描述,可见这里写图片描述也为的线性组合。由于为线性组合的最小正值,所以有0<=r并且小于s(因为r是除以s的余数),所以r=0,可知s|a,同理s|b,则s|d,因此可得s=d,命题得证。

好不容易证完了这个,下面我们首先来证明合数表示成素数乘积的存在性:
这里可以用反证法。假设有些合数不能表示为素数的乘积,假设n是其中最小的一个。
因为n是合数,所以必然有n = a*b(a,b均为不为1和你本身的整数) ,因为n是最小的不可以表示为素数乘积的数,所以a,b均可以表示为素数的乘积,那么n
也就可以表示为素数的乘积,与假设矛盾,所以得证。
下面证明唯一性(稍微繁一点):
首先要用到一个引理。如果素数p|a*b 则,p|a或p|b。证明:如果刚好p|a,那就直接证完啦。如果p不整除a,那么由上面证过的裴蜀定理,由于p是素数,那么
a和p的最大公约数为1,所以存在整数x,y,使得1=ax+py。两边同时乘以b得到,b=abx+bpy,等式右边显然可以被p整除,所以b也可以被p整除,即p|b,证毕。
下面开始证明合数都可以表示为一系列素数乘积的唯一性:
同样是反证法。假设
有些数可以用这种表示方法(均为素数的乘积)来表示
如n=p1^a1*p2^a2*……pn^an=q1^b1*q2^b2*q3^b3……*qn^bn
那么由刚刚的引理,我们可以知道这一系列素数里面可定有可以把n整除的,不妨设为p1,则p1| q1^b1*q2^b2*q3^b3*……*qn^bn,那么q1,q2,……,qn中 肯定有可 以被p1整除的,不妨设为q1,因为p1|q1,而p1和q1均为素数,那么p1=q1.
再看a1和b1,根据上面的方法,若a1>b1则p1^(a1-b1)p2^a2…….pn^an=q2^b2……pn^bn,那么q2,q3…qn中一定有可以被p1整除的,但p1=q1!=其他的qn,所以a1>b1不可能。同理a1小于b1也不可能,所以a1=b1,两边同除p1^a1,则有另一个比n晓得整数n0=p2^a2……pn^an=q2^b2……qn^bn可有两种表示方法与n是最小的假设矛盾,所以假设不成立。即唯一性得证。

2 0
原创粉丝点击