1

我在一次采访中被问到这个问题。我知道这是一个组合问题,但我不知道如何递归地解决这个问题。我主要是在寻找解决这类问题的方法。

给定一个元组,例如。(a, b, c)

输出 :

(*, *, *), (*, *, c), (*, b, *), (*, b, c), (a, *, *), (a, *, c), (a, b, *), (a, b, c)
4

6 回答 6

5

这是一个简单的单线使用itertools.product

list(itertools.product(*(('*', x) for x in seq)))

这给出了与请求相同的顺序:

>>> list(itertools.product(*(('*', x) for x in "abc")))
[('*', '*', '*'), ('*', '*', 'c'), ('*', 'b', '*'), ('*', 'b', 'c'), ('a', '*', '*'), ('a', '*', 'c'), ('a', 'b', '*'), ('a', 'b', 'c')]
于 2012-07-31T19:12:50.277 回答
1

实现这个特定问题的一种简单方法:对于一个 n 元组,只需从 0 循环到 2^n - 1,对于中间的每个整数,如果第 k 个二进制数字是 1,那么第 k 个位置在元组中是元组中的原始元素;如果那个数字是0,那么第k个位置是*。

当然,这种方法容易溢出,而且不是递归的;但是,它可以很容易地重写为递归程序(只需递归地探索每个二进制数字)。

于 2012-07-31T18:05:29.677 回答
1

假设顺序无关紧要,那就去吧。我使用了一个内部字符串来使其更容易实现。该代码也适用于任何 n 元组数组,因为n它是一个正整数。

关于这个实现的一些解释:将基本情况设置为 1 元组(在我的实现中,长度为 1 的字符串)。在这种情况下,返回*和参数的内容。否则,通过将当前元素替换为当前元素*或当前元素的内容来推进递归中的一个元素。

如果可以按照上述算法绘制决策树,则更容易理解。

def _combination(s):
    if len(s) == 1:
        return ['*', s]
    else:
        rest = _combination(s[1:])
        output = []
        for r in rest:
            output.append('*' + r)
            output.append(s[0] + r)
        return output

def combination(t):
    s = ''.join(c for c in t)
    result = _combination(s)
    output = []
    for r in result:
        output.append(format_tuple(r))
    print ', '.join(output)

def format_tuple(s):
    return '(' + ', '.join(s) + ')'

if __name__ == '__main__':
    t = ('a', 'b', 'c')
    combination(t)

程序的输出:

(*, *, *), (a, *, *), (*, b, *), (a, b, *), (*, *, c), (a, *, c), (*, b, c), (a, b, c)

根据凯文的评论更新。

于 2012-07-31T18:40:04.930 回答
1

类似于 clwen 的答案,但使用了非常适合组合问题的生成器函数:

def combinations(seq):
    if len(seq) == 1:
        yield ('*',)
        yield (seq[0],)
    else:
        for first in combinations([seq[0]]):
            for rest in combinations(seq[1:]):
                yield first + rest

print list(combinations("abc"))

输出:

[('*', '*', '*'), ('*', '*', 'c'), ('*', 'b', '*'), ('*', 'b', 'c'), 
('a', '*', '*'), ('a', '*', 'c'), ('a', 'b', '*'), ('a', 'b', 'c')]
于 2012-07-31T18:54:31.520 回答
1

每个涉及二进制计数的解决方案(比组合的好得多恕我直言)

t_str = raw_input("Enter Tuple Values Separated By Spaces:")
t = t_str.split()
n = len(t)
bin_template = "{0:0"+str(n)+"b}"
for i in range(2**n):
    bval = bin_template.format(i)
    solution= "("+",".join(["*" if bval[i] == "0" else t[i] for i in range(n)])+")"
    print solution

又好又短又快……它应该处理任意大小的元组,最大为 32(或者不管大整数是……而且可能更大,因为 python 使用任意大的整数)

于 2012-07-31T19:05:08.197 回答
0

由于这是一个面试问题,面试官可能正在寻找对递归原理的理解,因为这通常是这类组合问题的起点。

这段代码怎么样,以表明您理解:

def generate(x, state, level):
    if level == len(x):
        print state
    else:
        state[level] = '*'
        generate(x, state, level+1)
        state[level] = x[level]
        generate(x, state, level+1)


if __name__ == '__main__':
    x = [ 'a','b','c']
    generate(x,['*','*','*'], 0)
于 2012-08-01T17:23:57.933 回答