先上转载链接: chaoojie的博客
1.素数,曾称为质数。素数的定义为:
利用反证法可以证明,素数的个数是无穷的。欧几里得证明素数是无限的。反证法利用排中法的思想。
1.1素数有哪些性质?
可以看到,其中较为重要的性质有(2),(5),(6),(7),(8)。其中第八个性质可能会有快速解题的妙用。
2.如何求素数?
2.1首先介绍什么是合数。合数与质数是相对的概念。
合数的定义是:合数就是指自然数中除了能被1和本身整除外,还能被其他数(0除外)整除的数。合数也具有某些特殊的性质。
其中比较重要的个人认为应该是这一条:每一个合数都可以以唯一的形式被写成质数的乘积。即分解质因数。因为借助这一条性质,可以将需要比较的范围缩小到2~math.sqrt(n)。
2.2 如何求素数
思路:
1、任何一个合数(都指正整数,下同),都是几个质数的乘积。例如:18 = 2 * 3 * 3
2、如果一个数N不能整除M,则N也不能整除M*i,i=1, 2, 3....。即,N%M != 0,则 N%(M*i) != 0。例如,N不能整除2,那么N也不能整除6。因为,如果N能整除6,即,N%6 = 0,也就是 N%(2*3) = 0,也就是N能整除2,与前面矛盾。
3、如果N不是质数,那么N有满足1<d<=sqrt(N)(N的平方根)的一个质数因子 d 存在。因为如果N不是质数,根据条例1,N肯定可以分解为一堆质数的和,即肯定存在一个质数因子。如果找不到,那就说明N是质数,只能被1和自己本身整除。
方法:
A、依照判断素数的概念,我们可以从2~N-1,依次去除,看余数是否为0,复杂度为O(N)
B、改进一下,先判断 N%2 是否为0,如果不为0,即 N%(2*i) != 0(前面的条例2),所以只要再判断 3~N-1 之间的奇数即可,复杂度减半!为O(N/2)
同理,可以再判断 N%3 是否为0,如果不为0,则可以去掉后面的 3*i
C、其实,并不需要一直整除到N-1,而只要整除到 sqrt(N) 即可。如果 a < sqrt(N), b<sqrt(N),那么 a * b < sqrt(N)*sqrt(N) = N。如果b = N/a,那么b肯定是>=sqrt(N)。所以,只要判断小于等于sqrt(N)的数即可,再判断大于sqrt(N)的数就是在浪费时间了。
D、结合前面的 B 和 C,我们就可以先判断 N%2 是否为0,然后再判断 3~sqrt(N) 之间的奇数即可,复杂度为O(sqrt(N)/2)
E、根据条例3,如果N是质数,则N只能被1和N整除,如果N不是质数,那一定存在1<d<=sqrt(N)的一个质数因子。那么我们就可以取 2~sqrt(N) 之间的所有质数d,依次判断N%d 是否为0。如果判断均不等于0,就说明不存在这样的一个质数,也就是说N只能被1和本身整除,即N是质数。
关于各方法时间复杂度的分析和更快捷的方法点这里:
代码:代码来源:判断素数代码
/快速判断一个数是不是质数:(总共2步)
//1、判断能否被2整除
//2、遍历 3~Math.sqrt(value)这个范围
public static boolean IsPrime(int val){
boolean flag = true;
if((val & 1) == 0){
flag = false;
return flag;
}
for(int i=3; i<= Math.sqrt(val); i+=2){
if(val%i == 0){
flag = false;
break;
}
}
return flag;
}
---------------------
作者:下午茶609
来源:CSDN
原文:https://blog.csdn.net/u013565099/article/details/70327791
版权声明:本文为博主原创文章,转载请附上博文链接!
结束&