生成字符串的组合(不是排列)

时间:2011-12-01 20:26:43

标签: python algorithm combinations

我试图在Python中的“Programming Interviews Exposed”中实现该算法,如下所示,但它似乎不起作用(第2版第99页):

这个想法是生成一个字符串的所有组合(而不是排列),这样如果你输入“wxyz”,你就会得到“w,wx,wxy,wxyz,wxz,wy,wyz,wz ......”如果显示wz,那么zw无效。

def doCombine(strng, out, length, level, start):
    for i in range(start, length):
        out.append(strng[i])
        print out
        if (i < length - 1):
            doCombine(strng, out, length, level +1, i + 1)
        out = out[:-1]

x = list()
target = "wxyz"
print doCombine(target, x, len(target), 0, 0)

这可能有什么不妥之处?我得到相对垃圾输出。

4 个答案:

答案 0 :(得分:3)

在当前代码中,尝试将行out = out[:-1]更改为del out[-1]。这两个导致out删除了最后一项,但在当前代码中out被重新分配而不是使用相同的列表。这导致字符永远不会从原始列表中删除,这显然会使输出显着混乱。

进行更改后,输出结果如下:

>>> print doCombine(target, x, len(target), 0, 0)
['w']
['w', 'x']
['w', 'x', 'y']
['w', 'x', 'y', 'z']
['w', 'x', 'z']
['w', 'y']
['w', 'y', 'z']
['w', 'z']
['x']
['x', 'y']
['x', 'y', 'z']
['x', 'z']
['y']
['y', 'z']
['z']
None

答案 1 :(得分:2)

请参阅itertools模块中的combination()函数。

答案 2 :(得分:1)

我使用递归生成器重写了这个组合函数。输出是一个迭代器。

def combine(s):
    length = len(s)
    def gen(start, prepending=[]): #recursive generator
        if start == length-1:
            yield prepending + [s[start]]
        else:
            for i in range(start,length):
                current = prepending + [s[i]] #save the current list for reusing
                yield current
                for els in gen(i+1,current):
                    yield els
    for v in gen(0):
        yield v

s = "wxyz"
for v in combine(s):
    print(v)

立刻理解起来并不容易。

在联合生成器中使用相同的技术:Conjoin function made in functional style

另外,我在尝试理解它的工作原理时稍微重构了一下你的函数。 我会把它放在那些可能有兴趣放松理解的人身上。

def combine(s):
    out = []
    length = len(s)
    def loc(start):
        for i in range(start, length):
            out.append(s[i])
            print out
            if (i < length-1):
                loc(i+1)
            del out[-1]
    loc(0)

我进行了一些效率计算。

使用来自out的附加和删除的代码(原始海报的略微修改的代码用作生成器)比我在此答案中提供的代码快一点(我认为这是因为我使用过每次迭代prepending + [s[i]]在内存中创建一个新列表。同一列表上的附加和删除变得更快。)

详细信息: https://ideone.com/V3WIM

答案 3 :(得分:0)

out.append(strng[i])与描述的算法不匹配。你不想追加,你想要设置[level] = strng [i]