在f(x,y,z)
形式中,x
是给定的整数和,y
是序列的最小长度,z
是序列的最大长度。但是现在让我们假装我们正在处理一个固定长度的序列,因为否则我需要很长时间才能写出这个问题。
所以我们的函数是f(x,r)
,其中x
是给定的整数和,r
是可能序列列表中序列的长度。
对于x = 10
和r = 2
,这些是可能的组合:
1 + 9
2 + 8
3 + 7
4 + 6
5 + 5
让我们将它作为对列表存储在Python中:
[(1,9), (2,8), (3,7), (4,6), (5,5)]
所以用法如下:
>>> f(10,2)
[(1,9), (2,8), (3,7), (4,6), (5,5)]
回到原始问题,其中为(y,x)
范围内的每个长度返回一个序列。我之前定义的格式为f(x,y,z)
,并且遗漏了长度1
(其中y-z == 0
)的序列,这看起来像:
>>> f(10,1,3)
[{1: [(1,9), (2,8), (3,7), (4,6), (5,5)],
2: [(1,1,8), (1,2,7), (1,3,6) ... (2,4,4) ...],
3: [(1,1,1,7) ...]}]
因此输出是字典列表,其中值是对列表。不完全是最佳的。
所以我的问题是:
今天对所有这些算术问题感到抱歉。谢谢!
答案 0 :(得分:2)
itertools模块肯定会有用,因为我们正在处理预演 - 然而,这看起来像是一项家庭作业......
编辑:看起来很有趣,所以我会尝试。
编辑2 :这是你想要的吗?
from itertools import combinations_with_replacement
from pprint import pprint
f = lambda target_sum, length: [sequence for sequence in combinations_with_replacement(range(1, target_sum+1), length) if sum(sequence) == target_sum]
def f2(target_sum, min_length, max_length):
sequences = {}
for length in range(min_length, max_length + 1):
sequence = f(target_sum, length)
if len(sequence):
sequences[length] = sequence
return sequences
if __name__ == "__main__":
print("f(10,2):")
print(f(10,2))
print()
print("f(10,1,3)")
pprint(f2(10,1,3))
输出:
f(10,2):
[(1, 9), (2, 8), (3, 7), (4, 6), (5, 5)]
f(10,1,3)
{1: [(10,)],
2: [(1, 9), (2, 8), (3, 7), (4, 6), (5, 5)],
3: [(1, 1, 8),
(1, 2, 7),
(1, 3, 6),
(1, 4, 5),
(2, 2, 6),
(2, 3, 5),
(2, 4, 4),
(3, 3, 4)]}
答案 1 :(得分:1)
这个问题被称为 Integer Partitions ,并且已被广泛研究。
Here 您可以找到一篇文章,比较几种算法的性能(并提出一个特定的算法),但网上有很多参考文献。
答案 2 :(得分:0)
我刚写了一个递归生成器函数,你应该弄清楚如何从中获取一个列表......
def f(x,y):
if y == 1:
yield (x, )
elif y > 1:
for head in range(1, x-y+2):
for tail in f(x-head, y-1):
yield tuple([head] + list(tail))
def f2(x,y,z):
for u in range(y, z+1):
for v in f(x, u):
yield v
编辑:我只是看到它不是你想要的,我的版本也会生成重复项,只有订单不同。但您可以通过排序所有结果并检查重复的元组来简单地过滤掉它们。