簡體   English   中英

按給定間隔打印素數的反向列表

[英]printing reversed list of prime numbers with given interval

所以我想出了如何在給定的間隔內以相反的形式打印所有素數,但是對於一個測試用例,當他們將下限設置為1時,它也會打印出來。 我們知道1不是質數。

我的代碼是:

def prime_list_reversed(x, y):
"""
Input: the number x and y
Output: all prime numbers within [x,y] in reverse order

>>> prime_list_reversed(3, 10)
[7, 5, 3]
>>> prime_list_reversed(3, 3)
[3]
>>> prime_list_reversed(2, 2)
[2]
"""
assert type(x) == int, "first argument must be an integer"
assert type(y) == int, "second argument must be an integer"
assert x > 1, "1 is not a prime number"
assert y >= x,  "second argument must be >= the first one"

# YOUR CODE IS HERE #
lst = []
for i in range(x, y + 1):
    for c in range(2, i):
        if (i % c) == 0:
            break
    else:
        lst.append(i)
return list(reversed(lst))

一個測試用例

prime_list_reversed(1, 3)
[3,2,1]

您的素數檢查器將為i=1構造range(2, 1) ,但是該范圍為 確實:

>>> list(range(2, 1))
[]

因此,這意味着不對 i=1進行任何檢查,因此您的程序將其視為數。 我們可以在這里做兩件事:

  1. if語句檢查i == 1以避免發光;
  2. 確保外部范圍永遠不會首先發出1
def prime_list_reversed(x, y):
    # ...
    lst = []
    for i in range(max(2, x), y + 1):
        for c in range(2, i):
            if (i % c) == 0:
                break
        else:
            lst.append(i)
    return list(reversed(lst))

上面的方法解決了這個問題,但不是很優雅:我們首先構造一個列表,然后反轉該列表。 我們也可以簡單地反向發出元素:

def prime_list_reversed(x, y):
    # ...
    lst = []
    for i in range(y, max(2, x) - 1, -1):
        for c in range(2, i):
            if (i % c) == 0:
                break
        else:
            lst.append(i)
    return lst

現在,我們因此產生相反的元素。 但是代碼仍然效率低下:我們測試所有偶數。 但它足以測試如果一個數字可以分為2 ,如果沒有,我們可以省略支票46 ,等等,因為如果它不被divisable 2 ,那絕對是 divisable 46 而不是檢查數字是否可被2

def prime_list_reversed(x, y):
    # ...
    lst = []
    for i in range(y - (~y & 1), max(3, x) - 1, -2):
        for c in range(3, i, 2):
            if (i % c) == 0:
                break
        else:
            lst.append(i)
    if x <= 2 < y:
        lst.append(2)
    return lst

但是它仍然可以更有效。 如果將數字a除以b ,我們知道存在c = a / b 這意味着如果b>√a ,則c≤√a 我們可以利用此屬性:檢查√i就足夠了,因為我們知道否則我們已經通過另一部門進行了測試:

from math import ceil, sqrt

def prime_list_reversed(x, y):
    # ...
    lst = []
    for i in range(y - (~y & 1), max(3, x) - 1, -2):
        for c in range(3, ceil(sqrt(i))+1, 2):
            if not i % c:
                break
        else:
            lst.append(i)
    if x <= 2 < y:
        lst.append(2)
    return lst

最后,通常最好使它成為生成器,因為這使我們可以例如懶散地采用前10個元素:

from math import ceil, sqrt

def prime_list_reversed(x, y):
    # ...
    for i in range(y - (~y & 1), max(3, x) - 1, -2):
        for c in range(3, ceil(sqrt(i))+1, 2):
            if not i % c:
                break
        else:
            yield i
    if x <= 2 < y:
        yield 2

然后我們獲得1500之間的范圍:

>>> list(prime_list_reversed(1, 500))
[499, 491, 487, 479, 467, 463, 461, 457, 449, 443, 439, 433, 431, 421, 419, 409, 401, 397, 389, 383, 379, 373, 367, 359, 353, 349, 347, 337, 331, 317, 313, 311, 307, 293, 283, 281, 277, 271, 269, 263, 257, 251, 241, 239, 233, 229, 227, 223, 211, 199, 197, 193, 191, 181, 179, 173, 167, 163, 157, 151, 149, 139, 137, 131, 127, 113, 109, 107, 103, 101, 97, 89, 83, 79, 73, 71, 67, 61, 59, 53, 47, 43, 41, 37, 31, 29, 23, 19, 17, 13, 11, 7, 5, 3, 2]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM