Python中字符串的所有排列(递归)

时间:2014-04-16 18:04:36

标签: python recursion permutation

我需要在这个问题上取得进展。我定义了以下递归函数:

def perms(s):
  if(len(s)==1):
    return s

  res = ''
  for x in xrange(len(s)):

    res += s[x] + perms(s[0:x] + s[x+1:len(s)])

  return res + '\n'

perms(“abc”)目前返回:

abccb
bacca
cabba

期望的结果是

abc
acd
bac
bca
cab
cba

我在哪里错了?我怎样才能想出这个解决方案呢?

注意:我知道itertools函数。我试图了解如何为我自己的学习递归地实现排列。这就是为什么我希望有人指出我的代码有什么问题,以及如何以不同的方式来解决它。谢谢!

5 个答案:

答案 0 :(得分:14)

你去(递归排列):

def Permute(string):
    if len(string) == 0:
        return ['']
    prevList = Permute(string[1:len(string)])
    nextList = []
    for i in range(0,len(prevList)):
        for j in range(0,len(string)):
            newString = prevList[i][0:j]+string[0]+prevList[i][j:len(string)-1]
            if newString not in nextList:
                nextList.append(newString)
    return nextList

为了获得所有排列字符串的列表,只需使用输入字符串调用上面的函数即可。例如,

stringList = Permute('abc')

为了获得由换行符分隔的所有排列字符串的单个字符串,只需使用该函数的输出调用'\n'.join即可。例如,

string = '\n'.join(Permute('abc'))

顺便说一下,上面两个选项的print结果是相同的。

答案 1 :(得分:10)

排列的结果将是一个集合,让我们说一个列表。如果您这样想,它将使您的代码更清晰,如果需要,您可以将结果加入到单个字符串中。一个简单的例子是

def perms(s):        
    if(len(s)==1): return [s]
    result=[]
    for i,v in enumerate(s):
        result += [v+p for p in perms(s[:i]+s[i+1:])]
    return result


perms('abc')

['abc', 'acb', 'bac', 'bca', 'cab', 'cba']


print('\n'.join(perms('abc')))

abc
acb
bac
bca
cab
cba

答案 2 :(得分:1)

以下是代码:

def fperms(elements):
    if len(elements)<=1:
        yield elements
    else:
        for p in fperms(elements[1:]):
            for i in range(len(elements)):
                yield p[:i]+elements[0:1]+p[i:]

答案 3 :(得分:0)

不确定效率,但这也应该有效。

def find_permutations(v):
    if len(v) > 1:
        for i in perms(v):
            nv = i[1:]
            for j in perms(nv):
                print(i[0] + j)
    else:
        print(v)


def perms(v):
    if not hasattr(perms, 'original'):
        perms.original = v
        perms.list = []
    nv = v[1:] + v[0]
    perms.list.append(nv)
    if perms.original == nv:
        l = perms.list
        del perms.original
        del perms.list
        return l
    return perms(nv)

find_permutations('abc')

答案 4 :(得分:-3)

对于生成器(https://docs.python.org/3.3/tutorial/classes.html#generators)和yield来说,这是一个不错的选择。

尝试这样的事情(未经测试):

def permute_string(s):
    if len(s) <= 1:   #  "" and 1 char strings are their all their own permutaions.
        yield s
        return

    head = s[0] # we hold on to the first character
    for tail in permute_string(s[1:]) :   # permute the rest
        yield head + tail


# main
for permutation in permute_string(s) :
    print(permutation)

这是经典的排列算法:保留第一个字符和前置字符 它包含剩余字符的所有排列。这个特殊的函数是一个python生成器:这意味着它可以继续运行,同时逐个产生结果。在这种情况下,它可以更容易地专注于算法,而不必担心如何将数据返回给调用者的细节。