组合递归算法

时间:2014-07-09 00:34:42

标签: python recursion combinations

我需要编写一个递归函数,用Python计算列表中长度“n”的所有可能组合,而不导入itertools等任何内容。

所以到目前为止我所拥有的是:

if n == 0:
    return [[]]
elif lst == []:
    return []
else:
    rest = subsets(lst[1:], n-1)
    for next in lst:  # Loop through something?
        return lst[0] + rest #Add something?

我似乎缺乏对递归调用如何工作的理解,有人可以向我解释这个吗?

3 个答案:

答案 0 :(得分:1)

如果没有所需的输出规范,我们可以编写一些伪代码:

def combinations(sub, data_set, items_needed):
    if you dont need, return sub
    for item in data_set:
        append item to sub
        #pop() item from data_set?
        decrease items_needed # added one more, so we need one less
        combinations(new_sub, data_set, items_needed)

poping()与否取决于你想要(或没有)子集中的唯一项目。

如果你说你不想要[a,b]和[b,a],你还必须跟踪最后添加的项目的索引,以便只添加新项目以创建新的组合

def combinations(sub, data_set, index, still_needed):
    if you dont need any, return
    for i in range(index, len(data_set)):
        append data_set[i] to sub
        decrease still_needed
        combinations(sub, data_set, index+1, still_needed)

答案 1 :(得分:0)

这听起来像家庭作业一样危险。为什么它必须是递归的,因为这看起来很糟糕。

无论如何,递归地你正在做的是遍历列表中的每个元素,然后将其附加到长度为n-1的每个其他组合的开头。所以,如果你的列表是[1,2,3],你我想要一个调用堆栈看起来像这样的算法:

foo([], [1, 2, 3], n) ==
  foo([1], [2, 3], n - 1) +
  foo([2], [1, 3], n - 1) +
  foo([3], [1, 2], n - 1)

其中,

foo([1], [2, 3], n - 1) ==
  foo([1, 2], [3], n - 2) +
  foo([1, 3], [2], n - 2)

等...

只要n == 0,或者中间列表为空,就可以终止递归调用。你只需要返回第一个参数。

这一切都有意义吗? (如果需要的话,我可以编写代码。我认为如果你看一下所需的callstack,它应该主要放在一起。)

答案 2 :(得分:-1)

面对这样一个基本问题(一个经常用作入门级作业或在一些编程访谈中)的一个有用的技巧是看RosetteCode(你也可以从中学习给你留下深刻印象)喜欢" chrestomathy")之类的朋友。对于这个,我们特别发现:

#/usr/bin/env python
# From: http://rosettacode.org/wiki/Combinations#Python
def comb(m, lst):
if m == 0:
    return [[]]
else:
    return [[x] + suffix for i, x in enumerate(lst)
            for suffix in comb(m - 1, lst[i + 1:])]

...以及其他几十种语言的实现以供比较。

另一个方便的网站是PLEAC(对于"编程语言示例Alike Cookbook"项目)......虽然它的学术成就较少,并且倾向于更实用的编程任务。