素数检测算法

系统 1932 0

前言

今天做ACM的时候,遇到了素数的检测,检测一个范围内的素数的时候,如果用最简单的那种方法,超时严重,因此学习了一个新的素数检测算法——素数筛选法,这里也是跟大家分享一下

素数

素数的定义

一个大于1的整数,如果不能被除1和它本身之外的其它正整数整除,则是素数(又称质数)

合数的定义

一个大于1的整数,如果不是素数则是合数。其中能整除这个数的正整数叫做约数,不等于1也不等于合数本身的约数叫做非平凡约数。

注意:

1既不是素数也不是合数

检测素数

所谓素数检测,就是给定任意一个大于1的整数,判断这个整数是否为素数。

因子检测法

方法:就是从2到n-1一个个的拿来尝试,看能否整除n,如果存在能够整数n的(找到一个因子),则n不是素数,否则认为n是素数。实际,是不需要试探到n-1的,只要的n的二次方根即可,原因是:
设n = a * b,且a、b均为n非平凡约数,显然a > n的二次方根和b > n的二次方根不可能同时成立,因为同时成立时 a * b就会大于n,所以如果n存在非平凡约数,至少有一个小于等于n的二次方根,因此只要遍历到n的二次方根即可。

因子检测的实现代码如下(c):

      int isPrime(int n)
{
	int i, flag;
	flag = (n <= 1)? 0 : 1;
	
	for(i = 2; i <= sqrt(n); i ++)
	{
		if(n % i == 0)
		{
			flag = 0;
			break;
		}
	}
	return flag;
}
    

测试结果:

时间复杂度:

很明显,因子检测算法的时间复杂度是0(n的二次方根),一般来说,这个时间复杂度已经很牛叉了,但是如果我要求n以内所有的素数集合,那时间复杂度瞬间就到了n * n的二次方根,这个对于n很大时是不可忍受的

素数筛选法

利用素数因子检测法去超找n以内的所有素数,时间复杂度太高,不可忍受,因此这里介绍另外一种算法,素数筛选法,可以大大的节省时间,带来的直接功效是九度acm关于素数检测的题我瞬间ac,用素数因子检测基本都是wa。

原理:

当i是素数的时候,则i的所有倍数必然是合数。如果i已经判断不是素数了,那么找到i后面的质数来把这个质树的倍数筛掉。

求20以内素数的筛选过程:

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
第一步,因为所有的偶数和0,1必然不是质数,则将这些数的对应的value标记为flase,其余为true。
第二步:
i = 3,由于prime[3] = 1,则prime[6],prime[9],prime[12],prime[15],prime[18]均标记为0;
i = 4,由于prime[4] = 0,则continue,不做处理;
i = 5 > sqrt(20),算法结束

时间复杂度:

这个时间复杂度由于我的数学知识有限,也没法把计算过程解释出来,总之确实是很快,至于为什么i= 5就结束了,原因跟素数因子法里面的原理是一样的,因为n的因子必然有一个是小于等于n的二次方根的。

素数筛选法实现代码:

      void getPrimeArray(int *prime)
{
	int i, j;
	//初始化素数标识数组
	for(i = 0; i < max; i ++)
	{
		if((i == 2 || i % 2 != 0) && i != 1)
		{
			prime[i] = 1;
		} else
		{
			prime[i] = 0;
		}
	}
		
	//进行素数的筛选
	for(i = 2; i * i < max; i ++)
	{
		if(prime[i])
		{
			for(j = 2 * i; j < max; j += i)
			{
				prime[j] = 0;
			}
		}
	}

}
    

参考资料




素数检测算法


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论