判斷一個數是否爲質數(素數),三種思路和辦法

質數:一個大於1的自然數,除了1和它自身外,不能被其他自然數整除的數叫做質數;否則稱爲合數

最近在一個做題網站中遇到的一個問題,編寫一個函數,通過傳入的參數判斷這個數是不是質數。然後發現了三種解決辦法,下面按照效率高低依次進行分享。歡迎批評指正。

方法一:

根據解釋本身,傳入一個參數num,依次判斷num - 1中是否有num的約數,如果沒有就是質數,否則就是合數。

def is_prime1(num):
    i = 2
    while i < num-1:
        if num % i == 0:
            return False
        i += 1
    return True

第一種辦法需要對小於num 的每一個數進行判斷,效率最低。

方法二:

對傳入的參數num進行因式分解,只判斷左半部分,如果左邊沒有可以被整除的,右邊肯定也沒有。

from cmath import sqrt

def is_prime2(num):
    i = 2
    tmp = sqrt(num).real
    while i <= tmp:
        if num % i == 0:
            return False
        i += 1
    return True

方法三:

關於質數的分佈規律,大於等於5的質數一定和6的倍數相鄰,例如5和7 11和13 17和19 等等。證明:x >= 1 將x >= 5 的自然數表示如下:6x -2 ,6x -1,6x ,6x+1 ,6x+2 ,6x+3 ,6x+4 ,6x+5 ,6(x+1) ,6(x+1)+1 .....可以看到,不在6的倍數兩側的可以提去一個公約數:6x -2、6x+2、6x+3、6x+4 等於 2(3x-1)  2(3x+1) 3(2x+1) 2(2x+2)。所以他們一定不是素數,在除去6x本身,顯然,素數要出現只可能出現在6x的兩側。當然也存在6x兩側的也可能不是素數,還需要在判斷一次。而且我們判斷的步長可以改成6,

from cmath import sqrt

def is_prime3(num):
    if num in [2,3]:
        return True
    # 不在6的倍數兩側絕對不是質數
    elif (num % 6) != 1 and (num % 6) != 5 or num <= 1:
        return False
    tmp = sqrt(num).real
    i = 5
    # 在6的倍數兩側也可能不是質數
    while i <= tmp:
        if num % i == 0 or num % (i+2) == 0:
            return False
        i += 6
    return True

最後對這三個方法進行性能測試,同時處理100000以內的數

通過耗時對比可以看出來,方法二和方法三相差不是很多,但數據量很多的話差距就會明顯。方法一簡直了。

個人拙見,有更好的解法,歡迎批評指正

發佈了9 篇原創文章 · 獲贊 7 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章