一、质数
质数(素数)具有很多优良特性,可以认为它是构成一切自然数的“基础数”。质数应用很多,如:
1.在密码学上,公钥就是将秘密信息在编码时加入质数,任何人收到此信息后,若没有此收信人所拥有的密钥,则解密过程(实为寻找素数的过程)将会因为分解质因数耗时过久而失去意义。
2.在变速箱齿轮的设计上,相邻的两个大小齿轮齿数设计成质数,以增加两齿轮内两个相同的齿相遇啮合次数的最小公倍数,可增强耐用度减少故障。
3.在害虫的生物生长周期与杀虫剂使用之间的关系上,杀虫剂的质数次数的使用也得到了证明。实验表明,质数次数地使用杀虫剂是最合理的:都是使用在害虫繁殖的高潮期,而且害虫很难产生抗药性。
4. 以质数形式无规律变化的导弹和鱼雷可以使敌人不易拦截。
5.多数生物的生命周期也是质数(单位为年),这样可以最大程度地减少碰见天敌的机会。
二、互质数
互质数表示两个数的公约数只有1。判别方法主要有以下几种(不限于此):
(1)两个质数一定是互质数。例如,2与7、13与19。
(2)一个质数如果不能整除另一个合数,这两个数为互质数。例如,3与10、5与26。
(3)相邻的两个自然数或者奇数都是互质数。如15与16、49与51。
(4)较大数是质数的两个数是互质数。如97与88。
(5)较小数是质数,较大数不是较小数的倍数的两个数是互质数。如7和16。
(6)两个数都是合数(二数差又较大),小数所有的质因数,都不是大数的约数,这两个数是互质数。如357与715,357=3×7×17,而3、7和17都不是715的约数,这两个数为互质数。等等。
三、算法举例:判断N是否质数
基本方法 1. 简单枚举法判断
利用枚举法遍历1-N,计算在N以内,哪些数没有2以上的因子。
boolean isPrime(int n) {
if(n < 2) return false;
for(int i = 2; i < n; i++) {
if (n % i == 0) {
return false;
}
}
return true;
}
可见,这种简单算法的复杂度为O(n)。
改进方法 2. 因子分析法
对任意大于2的正整数c,若c为合数,则可以表示为 c=a*b,其中a<b,且均为正整数。考虑到a、b具有对称性,所以a<=sqrt(c)。 因此,若想判断N是否可以分解,则最多只需要从2遍历到sqrt(n)即可,余下的操作都是重复!
boolean isPrime(int n) {
if(n < 2) return false;
for(int i = 2, end = Math.sqrt(n); i <= end; i++) {
if (n % i == 0) {
return false;
}
}
return true;
}
此时,时间复杂度将为O(sqrt(n))。
改进方法 3. 因子分析+提出元素法
鉴于只有奇数才可能是素数,所以进一步改进算法,遍历的时候从3开始,步进为2:
boolean isPrime(int n) {
if(n < 2) return false;
for(int i = 3, end = Math.sqrt(n); i <= end; i += 2) {
if (n % i == 0) {
return false;
}
}
return true;
}
此时,时间复杂度将为O(sqrt(n)/2)。