质数判断(你有珠心算,我有珠心算法)

时间:2021-02-22 10:58:52
看过《最强大脑》的小伙伴应该都知道珠心算。尤其是在中国队对阵日本队时,那种紧张的气氛婉如世纪大战一触即发。对于大多数和我一样的普通小老百姓而言就只剩下感叹的份了。
所谓的珠心算其实就是“珠算”和“心算”的结合体。一个庞大的数字在瞬间就能分辨是否是质数,这种计算量要是让我来,怎么也得废上好几本笔记本了。在电影《异次元杀阵》中也用到了质数判断来作为阻拦主角一行人的难题,没看过的可以去补补哦。
那么作为一个码农我今天要讲解的是如何使用代码来瞬间完成大数字的质数判断。代码部分其实很简单,如果没兴趣了解原理的话直接跳到最后看代码就可以了。


一、什么是质数

质数就是只能被1和本身除尽的数。

根据这个特点可以把这个数(n)依次除以2 ~ (n-1)。这样就可以判断数字n是否是质数。但是这种办法显得异常的蠢,它的时间复杂度为O(n)。


二、列举偶数质数

在偶数当中只有2符合质数的特点,所以偶数中也只有一个质数2。

根据这个特点可以在上述方法上进行改进,在依次除以2 ~ (n-1)之前加上一个非偶数判断就能减少一半的工作量。


三、最小偶质数和最小奇质数的最小公约数

最小偶质数2,最小奇质数3(质数的取值范围是大于1的自然数,因此1不能作为最小奇质数)。2和3的最小公约数(它是一个能被若干个整数同时均整除的整数。如果一个整数同时是几个整数的约数,称这个整数为它们的公约数)为6。

根据这个特点可以把跨度定为6。因为在6x中只有(6x-1)和(6x+1)会出现质数,别的数都能够被2或3整除。这样一来在2 ~ (n-1)之间又筛出了三分之一的奇数。


四、最大复杂度

由于没有找到该特点的学术名,“最大复杂度”是本人在书写该篇文章时提出。如不恰当或难以理解请忽略题名直接看下面内容:
先来一个假设,如果一个数不为质数且有5、7、35等因数。那么在进行除法操作时只需要除到5便可以判断出该数不是一个质数。由此可见最复杂的情况便是该数除去1和本身之外只有一个因数(一个质数的平方),例如49。

根据这个特点可以把一个数开根,只需要除到开根数如果没有被整除便是质数,被整除便不是质数。


结合以上所有特点得到下面质数判断算法:
public Boolean demo(int num){
    if(num ==2|| num==3 ){
        return true ;  
    }  
    if(num %6!= 1&&num %6!= 5) {
        return false ; 
    } 
    int tmp =(int)Math.sqrt(num);  
    for(int i= 5;i <=tmp; i+=6 ) {
        if(num %i== 0||num %(i+ 2)==0 ){
            return false ; 
        }  
    }  
    return true ;
}