1. 程式人生 > >判斷質數/素數——我知道的最快的方法

判斷質數/素數——我知道的最快的方法

標準版:大部分人都知道的比較快的方法:判斷從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個,

時間複雜度O(sqrt(n)/3)。

在高配版和尊享版中,都是一個剪枝的思想,高配版中裁剪了不必要的偶數,尊享版中裁剪了不和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;
}