素数检测的几种算法
素数,又称质素,除了能表示为它本身和1的乘积以为,不能表示为任何其它两个整数的乘积。
一、试除法
根据素数的定义,假设要判断的自然数为n,那么最简单的方法便是用2~(n-1)之间的数字依次枚举试除一遍,如果能整除,那说明这个数不是素数,显然,此种算法的效率极低。初学C语言的人会使用另一种改进的试除法,那便是除数不用取遍2~(n-1),而是取2~(int)sqrt(n),但是当n很大时,此种算法的时间消耗也很大,也是不可取的。
二、筛选法
筛选法事一种比较高校的判断素数的方法,能够一次性的筛选除某个区间的素数。算法的基本原理也是利用了素数的定义,在某个范围内,依次去掉2的倍数,3的倍数,5的倍数……以此类推,一直到所有小于或等于n的数字的倍数都被去掉为止。这就像一面筛子,把某个区间范围内满足条件的数留下来,其余的数字去掉,最后判断此区间内的某个数是否为素数时,时间复杂度就为O(1)。很显然,时间的主要消耗都在于数字的筛选上。利用给数组单元置零的方法来实现,创建一个数组a[i],i=1、2、3……,用memset()函数将其全部置1,当i不是素数,则将a[i]置零。
代码实现如下:
#define MAX N /*N为设置的某个数,确定一个判断区间*/
int isprime[MAX];
void is_prime1()
{
int i,j;
memset(isprime,1,sizeof(isprime));
for(i=2;i{
if(isprime[i])
for(j=2*i;jisprime[i]=0;
}
}
此种筛选算法可以优化为二次筛选,就是要求n以内的素数,就先把sqrt(n)内的素数求出来,再用已经求得的素数来筛选后面的合数。
2007年,复旦的xreborner将筛选法进一步改进为真正的线性时间复杂度,改进算法是增加了一个数组,记录已经找到的素数,通过这些已经找到的素数,来筛掉后面的数。
三、费马测试
费马算法是利用数学结论来进行素数检验的方法,利用了费马定理得到推论,若