判斷質數/素數——我知道的最快的方法
阿新 • • 發佈:2019-01-02
標準版:大部分人都知道的比較快的方法:判斷從2到sqrt(n)是否存在其約數,時間複雜度O(sqrt(n))
高配版:判斷2之後,就可以判斷從3到sqrt(n)之間的奇數了,無需再判斷之間的偶數,時間複雜度O(sqrt(n)/2)
尊享版:
首先看一個關於質數分佈的規律:大於等於5的質數一定和6的倍數相鄰。例如5和7,11和13,17和19等等;
證明:令x≥1,將大於等於5的自然數表示如下:
··· 6x-1,6x,6x+1,6x+2,6x+3,6x+4,6x+5,6(x+1),6(x+1)+1 ···
可以看到,不在6的倍數兩側,即6x兩側的數為6x+2,6x+3,6x+4,由於2(3x+1),3(2x+1),2(3x+2),所以它們一定不是素數,再除去6x本身,顯然,素數要出現只可能出現在6x的相鄰兩側。因此在5到sqrt(n)中每6個數只判斷2個,
在高配版和尊享版中,都是一個剪枝的思想,高配版中裁剪了不必要的偶數,尊享版中裁剪了不和6的倍數相鄰的數,雖然都沒有降低時間複雜度的階數,但都一定程度上加快了判斷的速度。
在此給出尊享版C++程式碼:
#include <iostream> #include <math.h> using namespace std; int isPrime(int n) { //返回1表示判斷為質數,0為非質數,在此沒有進行輸入異常檢測 float n_sqrt; if(n==2 || n==3) return 1; if(n%6!=1 && n%6!=5) return 0; n_sqrt=floor(sqrt((float)n)); for(int i=5;i<=n_sqrt;i+=6) { if(n%(i)==0 | n%(i+2)==0) return 0; } return 1; } int main() { int flag; flag=isPrime(37); cout<<flag<<endl; return 0; }