我想創建一個 python 程式,它回傳將整數(比如 n)寫入為 r 個正整數之和的所有可能方式。
我的代碼如下:
def f(n,r):
cache = {}
l1 = []
for i in range(1,n):
l1.append([i,n-i])
if r ==2 :
cache[tuple([n,r])] = l1
return l1
elif (n,r) in cache:
return cache[(n,r)]
else:
lr = []
for i in range (1,n):
for x in f(n-i,r-1):
x.append(i)
lr.append(x)
cache[tuple([n,r])] = lr
return lr
對于 r 的任何值,它在 n = 20 之前都可以正常作業,但在那之后它真的很慢,這是意料之中的,因為重復很慢。我怎樣才能在不使用重復的情況下實作這一目標?
uj5u.com熱心網友回復:
按字典順序生成。
請注意,由于磁區數量呈指數增長,對于較大的 n,r 值,任何生成方法都不會很快。
from itertools import combinations
def parts(n,r):
result = []
for comb in combinations(range(n-1), r-1):
parts = [comb[0] 1] [comb[i]-comb[i-1] for i in range(1,r-1)] [n-1-comb[-1]]
#print(comb, parts)
result.append(parts)
return(result)
print(parts(6,3))
>>>[[1, 1, 4], [1, 2, 3], [1, 3, 2], [1, 4, 1], [2, 1, 3], [2, 2, 2],
[2, 3, 1], [3, 1, 2], [3, 2, 1], [4, 1, 1]]
uj5u.com熱心網友回復:
一個簡單的遞回lru_cache:
>>> from functools import lru_cache
>>> @lru_cache(None)
... def f(n, r):
... if r == 1:
... return (n,),
... return tuple((i,) comb for i in range(1, n) for comb in f(n - i, r - 1))
...
>>> f(20, 3)
((1, 1, 18),
(1, 2, 17),
(1, 3, 16),
...
(17, 1, 2),
(17, 2, 1),
(18, 1, 1))
注意:如果我們固定r為 10 并繼續增加n,函式的運行時間還是會逐漸變得無法接受,因為每增加 1 次,得到的結果的長度會大大增加,而且元組(或串列)也會越來越多:
>>> {i: len(f(i, 10)) for i in range(10, 30)}
{10: 1,
11: 10,
12: 55,
13: 220,
14: 715,
15: 2002,
16: 5005,
17: 11440,
18: 24310,
19: 48620,
20: 92378,
21: 167960,
22: 293930,
23: 497420,
24: 817190,
25: 1307504,
26: 2042975,
27: 3124550,
28: 4686825,
29: 6906900}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/507884.html
上一篇:無法實作Maclaurin的系列
下一篇:如何翻轉一個矩形?
