我正在研究一个发现所有k位数字的数字加总给定n的问题。
我发现了如何执行此操作并将其作为整数分区问题进行处理,但是我希望只能输入n和k个数字(没有max_element),但是当我尝试从代码中删除它时,它似乎没有继续工作。
我该如何改变它并扭转它?
def c(n, k, max_element):
allowed = range(max_element, 0, -1)
def helper(n, k, t):
if k == 0:
if n == 0:
yield t
elif k == 1:
if n in allowed:
yield t + (n,)
elif 1 * k <= n <= max_element * k:
for v in allowed:
yield from helper(n - v, k - 1, t + (v,))
return helper(n, k, ())
for p in c(5, 3, 3):
print(p)
我尝试使用反向方法,但显然在生成器中不起作用。
结果:
(3, 1, 1)
(2, 2, 1)
(2, 1, 2)
(1, 3, 1)
(1, 2, 2)
(1, 1, 3)
预期结果:
113 122 131 212 221 311
此功能应有效
def c(n, k, max_element):
allowed = range(max_element, 0, -1)
def helper(n, k, t):
if k == 0:
if n == 0:
yield t
elif k == 1:
if n in allowed:
yield t + (n,)
elif 1 * k <= n <= max_element * k:
for v in allowed:
yield from helper(n - v, k - 1, t + (v,))
return helper(n, k, ())
def reversed_iterator(iter):
return reversed(list(iter))
for p in reversed_iterator(c(5, 3, 3)):
print(p)
这里是输出:
(1, 1, 3)
(1, 2, 2)
(1, 3, 1)
(2, 1, 2)
(2, 2, 1)
(3, 1, 1)
这里有几个问题;首先是由于range(max_element, 0, -1)
,您需要按顺序排列数字,并且此代码以相反的顺序生成它们。另一个问题是,由于要生成数字,因此最小元素应为0,最大元素应始终为9。我们可以通过将该范围更改为range(10)
来解决这两个问题。
[我们仍然需要注意不要生成以0开头的数字,因此我们将allowed
用作参数,并仅将range(1, 10)
用作第一位数字。
供参考,此生成器功能的代码来自my answer to another question。
def c(n, k): def helper(n, k, t, allowed): if k == 0: if n == 0: yield t elif k == 1: if n in allowed: yield t + (n,) elif 0 <= n <= 9 * k: for v in allowed: yield from helper(n - v, k - 1, t + (v,), range(10)) return helper(n, k, (), range(1, 10))
示例:
>>> for p in c(5, 3):
... print(p)
...
(1, 0, 4)
(1, 1, 3)
(1, 2, 2)
(1, 3, 1)
(1, 4, 0)
(2, 0, 3)
(2, 1, 2)
(2, 2, 1)
(2, 3, 0)
(3, 0, 2)
(3, 1, 1)
(3, 2, 0)
(4, 0, 1)
(4, 1, 0)
(5, 0, 0)