Python中查找素數的不同方法分析


  如果您參與競爭性編程,您可能會熟悉與Prime數相關的問題是問題設定者的選擇之一。在這里,我們將討論如何優化您的函數,該函數檢查給定范圍集中的Prime數,並且還將計算執行它們的時間。按照定義,Prime數是一個正整數,只能由自身和1整除。

  1. 例如:2,3,5,7。但是,如果一個數字可以被分解為較小的數字,則稱為復合數。
  2. 例如:4 = 2 * 2,6 = 2 * 3
  3. 整數1既不是素數也不是復數。檢查數字是否為素數很容易,但有效檢查需要一些努力。

方法1

  現在讓我們使用第一個函數來檢查數字(例如n)是否為素數。在這種方法中,我們將測試從2到n-1的所有除數。我們將跳過1和n。如果n可被任何除數整除,則該函數將返回False,否則返回True。
以下是此方法中使用的步驟:

  1. 如果整數小於等於1,則返回False。
  2. 如果給定的數字可以被2到n中的任何數字整除,則該函數將返回False
  3. 否則它將返回True
# Python Program to find prime numbers in a range 
import time 
def is_prime(n): 
    if n <= 1: 
        return False
    for i in range(2,n): 
        if n % i == 0: 
            return False
    return True
  
# Driver function 
t0 = time.time() 
c = 0 #for counting 
  
for n in range(1,100000): 
    x = is_prime(n) 
    c += x 
print("Total prime numbers in range :", c) 
  
t1 = time.time() 
print("Time required :", t1 - t0) 

輸出

總質數范圍:9592
所需時間:60.702312707901

  在上面的代碼中,我們檢查從1到100000的所有數字,無論這些數字是否為素數。它具有如圖所示的巨大運行時間。運行大約需要1分鍾。這是一種簡單的方法,但需要花費大量時間才能運行。因此,它在競爭性編程中不是首選。

方法2

  在這種方法中,我們通過減少我們檢查的除數​​的數量來使用一個簡單的技巧。我們發現有一條細線充當鏡子,顯示線下方的因子分解和線上方的因子分解正好相反。將因子分成兩半的線是數字的平方根的線。如果數字是一個完美的正方形,我們可以將線移1,如果我們可以得到划分的線的整數值。

36 = 1 * 36          
   = 2 * 18
   = 3 * 12
   = 4 * 9
------------
   = 6 * 6
------------
   = 9 * 4
   = 12 * 3
   = 18 * 2
   = 36 * 1

  在這個函數中,我們計算一個整數,比如max_div,它是數字的平方根,並使用Python的數學庫得到它的最低值。在最后一個例子中,我們從2迭代到n-1。但在這方面,如圖所示,我們將除數減少了一半。您需要導入數學模塊以獲得樓層和sqrt功能。
以下是此方法中使用的步驟:

  1. 如果整數小於等於1,則返回False。
  2. 現在,我們將需要檢查的數字減少到給定數字的平方根。
  3. 如果給定的數字可以被2到該數字的sqaure根中的任何數字整除,則該函數將返回False
  4. 否則它將返回True
# Python Program to find prime numbers in a range 
import math 
import time 
def is_prime(n): 
    if n <= 1: 
        return False
  
    max_div = math.floor(math.sqrt(n)) 
    for i in range(2, 1 + max_div): 
        if n % i == 0: 
            return False
    return True
  
# Driver function 
t0 = time.time() 
c = 0 #for counting 
  
for n in range(1,100000): 
    x = is_prime(n) 
    c += x 
print("Total prime numbers in range :", c) 
  
t1 = time.time() 
print("Time required :", t1 - t0) 

輸出

總質數范圍:9592
所需時間:0.4116342067718506

⏡⏡在上面的代碼中,我們檢查從1到100000的所有數字,無論這些數字是否為素數。它比以前的方法花費的時間相對較短。這是一個有點棘手的方法,但在代碼的運行時間方面有很大的不同。因此,它在競爭性編程中更為優選。

方法3

⏡⏡現在,我們將代碼優化到下一級別,這比前一種方法花費的時間更短。您可能已經注意到,在最后一個示例中,我們遍歷每個偶數,直到極限,這是浪費。要注意的是除了兩個以外的所有偶數都不能是素數。在這種方法中,我們踢出所有偶數以優化我們的代碼,並且只檢查奇數除數。
以下是此方法中使用的步驟:

  1. 如果整數小於等於1,則返回False。
  2. 如果數字等於2,則返回True。
  3. 如果數字大於2且可被2整除,則它將返回False。
  4. 現在,我們檢查了所有偶數。現在,尋找奇數。
  5. 如果給定的數字可以從跳過所有偶數的數字的3到平方根中的任何數字整除,則該函數將返回False
  6. 否則它將返回True
# Python Program to find prime numbers in a range 
import math 
import time 
def is_prime(n): 
    if n <= 1: 
        return False
    if n == 2: 
        return True
    if n > 2 and n % 2 == 0: 
        return False
  
    max_div = math.floor(math.sqrt(n)) 
    for i in range(3, 1 + max_div, 2): 
        if n % i == 0: 
            return False
    return True
  
# Driver function 
t0 = time.time() 
c = 0 #for counting 
  
for n in range(1,100000): 
    x = is_prime(n) 
    c += x 
print("Total prime numbers in range :", c) 
  
t1 = time.time() 
print("Time required :", t1 - t0) 

輸出

總質數范圍:9592
所需時間:0.23305177688598633

⏡⏡在上面的代碼中,我們檢查從1到100000的所有數字,無論這些數字是否為素數。它比所有以前運行程序的方法花費的時間相對較短。檢查素數是最有效和最快捷的方法。因此,它在競爭性編程中是最優選的。下次在競爭性編程中嘗試任何問題時,請使用此方法以獲得最佳結果。

篩選方法

此方法打印小於或等於給定數量n的所有素數。例如,如果n為10,則輸出應為“2,3,5,7”。如果n為20,則輸出應為“2,3,5,7,11,13,17,19”。
該方法被認為是生成小於給定數量n的所有素數的最有效方法。它被認為是生成素數列表的最快方法。此方法不適合檢查特定數字。該方法優選用於生成所有素數的列表。

# Python Program to find prime numbers in a range 
import time 
def SieveOfEratosthenes(n): 
       
    # Create a boolean array "prime[0..n]" and  
    # initialize all entries it as true. A value  
    # in prime[i] will finally be false if i is 
    # Not a prime, else true. 
    prime = [True for i in range(n+1)] 
      
    p = 2
    while(p * p <= n): 
           
        # If prime[p] is not changed, then it is  
       # a prime 
        if (prime[p] == True): 
               
            # Update all multiples of p 
            for i in range(p * 2, n + 1, p): 
                prime[i] = False
        p += 1
    c = 0
  
    # Print all prime numbers 
    for p in range(2, n): 
        if prime[p]: 
            c += 1
    return c 
  
# Driver function 
t0 = time.time() 
c = SieveOfEratosthenes(100000) 
print("Total prime numbers in range:", c) 
  
t1 = time.time() 
print("Time required:", t1 - t0) 

輸出:

總質數范圍:9592
所需時間:0.0312497615814209

注意:所有過程所需的時間可能因編譯器而異,但不同方法所需的時間順序將保持不變。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM