关于素数的判定小记

1、整除性

      若a和b都为整数,a整除b是指b是a的倍数,a是b的约数(因数、因子),记为a|b。整除的大部分性质都是显而易见的,为了阐述方便,我给这些性质都随便起了个名字。

      i)  任意性,若a|b,则对于任意非零整数m,有am|bm。

      ii) 传递性,若a|b,且b|c,则a|c。

      iii) 可消性,若a|bc,且a和c互素(互素的概念下文会讲到),则a|b。

      iv) 组合性,若c|a,且c|b,则对于任意整数m、n,有c|(ma+nb)。

      拿一个我还未出生时的初二数学竞赛题就能概括整除的性质了。

     【例题1】(公元1987年初二数学竞赛题) x,y,z均为整数,若11|(7x+2y-5z),求证:11|(3x-7y+12z)。 

      非常典型的一个问题,为了描述方便,令a = (7x+2y-5z),b = (3x-7y+12z),通过构造可以得到一个等式:4a + 3b = 11(3x-2y+3z),则3b = 11(3x-2y+3z) - 4a。

      任意性+组合性,得出 11 |(11(3x-2y+3z) - 4a) = 11|3b。

      可消性,由于11和3互素,得出 11 | b,证明完毕。

      2、素数

      a.素数与合数

      素数又称质数,素数首先满足条件是要大于等于2,并且除了1和它本身外,不能被其它任何自然数整除;其它的数称为合数;而1既非素数也非合数。

      b.素数判定

      如何判定一个数是否为素数?

      i)  对n做[2, n)范围内的余数判定(C++中的'%'运算符),如果有至少一个数用n取余后为0,则表明n为合数;如果所有数都不能整除n,则n为素数,算法复杂度O(n)。

      ii) 假设一个数能整除n,即a|n,那么n/a也必定能整除n,不妨设a <= n/a,则有a^2 <= n,即a <= sqrt(n)(sqrt表示对n开根号),所以在用i)的方法进行取余的时候,范围可以缩小到sqrt(n),所以算法复杂度降为O( sqrt(n) )。

      iii) 如果n是合数,那么它必然有一个小于等于sqrt(n)的素因子,只需要对sqrt(n)内的素数进行测试即可,需要预处理求出sqrt(n)中的素数,假设该范围内素数的个数为s,那么复杂度降为O(s)。

      c.素数定理

      当x很大时,小于x的素数的个数近似等于x/ln(x),其中ln(x)表示x的自然对数,用极限表示

                                                                \lim_{x \to +\infty}\frac{\pi (x)}{x/ln(x)}= 1

      从这个定理可以发现,程序中进行素数判定的时候,循环次数明显减少。

int primenumber1(int n){
	for(int i=2;i<=n/2;i++){
		if(n%i==0)  return 0;
	}
	if(n==1) return 0;
	return 1;
}

用这篇博客记录我的一点点小疑惑,为什么素数的判断到sqrt(n)就可以了。

数论还是要用到很多。。。

你可能感兴趣的:(经验分享)