写在前面
本人在自学C程序设计(第五版,谭浩强著)这本书时,其中算法一章,素数判定一例,让我疑惑了一会。本文内容包括素数的定义,素数的三种判断方式及其详细解释。
素数(也称质数)的定义:大于1的自然数,只能被1和它自身整除。(用专业术语来说,因数只有1和它自身)
本质上,对于任何一个大于1的自然数,它都有因数,只是我们把因数为1和它自身的数特意划分为素数(质数);那么素数的反面,叫合数。
素数的判断方式:
第一种方式,由素数的定义,我们不妨想着,设这个数为n(n大于1),它的因数肯定有1和n,它可能有其它因数,这时它为合数;它也可能没有其它因数,这时它为素数。
显然,1与n不用作为除数,只需要对2 ~ n-1讨论。
若我们把2 ~ n-1作为除数都除一遍,余数为零代表“能整除,该除数是它的因数”;余数不为零时代表“不能整除,该除数不是它的因数”。
所以确定的范围2 ~ n-1
如果n比较小,那么第一种方式运算量不大,但是如果n很大,那么运算量庞大。
第二种,在第一种方法基础上,我们试想着如何把除数范围缩小。
首先,我们知道,一对因数的乘积是n,如2与n/2,3与n/3等,每一对的乘积均为n。
所以,很显然,在范围2 ~ n-1中,最小的可能存在的因数是2,最大的可能存在的因数是n/2。
这是由于每一对因数的乘积为定值n,最小因数对应的另一因数就是最大因数。
因此我们确定了一个新的范围,即2~n/2。
第三种,在第二种的方法基础上,假设存在的因数如下从小到大排列:
2、3............... √n 、√n..............n/3、n/2
把2和n/2 ,3和n/3等因数,从小到大排列,我们可以知道两点:
第一点,如果把因数2作为除数,那么因数n/2就不用作为除数,2能整除,那么n/2也能整除,同样的,2不能,n/2也不能。
所以我们只需要取每一对因数中的一半,如2与n/2只需取2;3与n/3只需取3,等等。
第二点,最中间的一对因数是√n与√n。
若分析,会发现最左边(最小因数2)与最右边(最大因数n/2)是一对因数,从两端开始,依次向中间也是一对(如3与n/3)。
一对因数中,较小的因数从2开始逐渐增大,较大的因数从n/2开始逐渐减小,理想中,最终两因数相等,既为根号n与根号n。
按照第一点,我们每一对因数只需取一半,那么取2~√n或者√n~n/2
所以我们可以进一步的缩小范围,即2~√n