[英]How can I make Python code more efficient?
新手來了我有這個代碼,它顯示達到某個數字的所有可能的總和。 但是它的復雜度太高,當數字太高時需要太長時間。 我怎樣才能把它重構為更簡單的東西?
import itertools
def combos(n):
result = []
for i in range(n,0,-1):
for seq in itertools.combinations_with_replacement(range(1,n+1), i):
if sum(seq) == n:
seq = list(seq)
result.append(seq)
return(result)
combos(4)
輸出:
[[1,1,1,1],[1,1,2],[1,3],[2,2],[4]]
遞歸版本可能是這樣的:
def combinations_max_sum(sum_max, i_max=None):
if sum_max == 0:
return [()]
if not i_max or i_max > sum_max:
i_max = sum_max
combinations = [(i, *right_part)
for i in range(i_max, 0, -1)
for right_part in combinations_max_sum(sum_max-i, i_max=i)]
return combinations
測試:
print(combinations_max_sum(4)) # [(4,), (3, 1), (2, 2), (2, 1, 1), (1, 1, 1, 1)]
print(combinations_max_sum(4, i_max=1)) # [(1, 1, 1, 1)]
print(combinations_max_sum(5))
# [(5,), (4, 1), (3, 2), (3, 1, 1), (2, 2, 1), (2, 1, 1, 1), (1, 1, 1, 1, 1)]
分解問題的想法:一組組合可以寫成一個數字,該數字與所有組合的總和為n
減去第一個數字。
不處理重復的更簡單的代碼可能是這樣的:
def combinations_with_repetition(n):
if n == 0:
return [()]
combinations = [(i, *right_part) # concatenation
for i in range(1, n+1) # for all possible first number
for right_part in combinations_with_repetition(n-i)]
# ^ all possible combinations
# given the first number i
return combinations
這使:
combinations_with_repetition(3)
# [(1, 2), (1, 1, 1), (2, 1), (3,)]
(1, 2)
和(2, 1)
類似,為了防止這種情況,添加了i_max
參數(參見第一個函數)。 這里的想法是始終按降序排列。 右邊的數字總是等於或小於左邊的數字。 這個最大數字作為參數傳遞,循環從它開始,而不是要求的總和。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.