Python中置换的递归实现

抱歉,已经有很多关于此问题的帖子.但是,我很难知道自己的实现中哪里出了问题.因此,我试图编写一个接受字符串并以列表形式返回所有可能排列的函数.

从理论上讲,它应该像这样:

allPermutations(“ abc … z”)= [a allPermutations(b,c,… z),b allPermutations(a,c … z)…]

我当前的实现在对字符串“ Hello”进行测试时,会输出一堆重复的排列.谁能帮我看看我要去哪里错了.感谢您的协助!

这是代码:

def allPermutations(strng):
    if len(strng) ==1:
        return [strng]
    perm_list = []
    for i in strng:
        smallerStr = strng.replace(i,"",1)
        z = allPermutations(smallerStr)

        for t in z:
            perm_list.append(i+t)        
    return perm_list

解决方法:

如果您有重复的字母,您将有重复的排列,因为这就是您的逻辑.

例如,使用“ Hello”,对于第一个l,您将为“ Helo”的每个排列添加“ l”权限,然后对于第二个l,您将再次为“’hello”的每个排列添加“ l”权限.嘿!

有几种方法可以显示没有重复的排列.最简单的方法是循环遍历set(strng)而不是strng:

def allPermutations(strng):
    if len(strng) ==1:
        return [strng]
    perm_list = []
    for i in set(strng):
        smallerStr = strng.replace(i,"",1)
        z = allPermutations(smallerStr)

        for t in z:
            perm_list.append(i+t)        
    return perm_list

附带说明一下,您几乎永远不想做这样的事情:

for i in strng:
    smallerStr = strng.replace(i,"",1)

… 要么

for x in lst:
    idx = lst.find(x)

除了明显的性能问题,即不必要地搜索已经拥有的东西之外,如果您有任何重复的元素,也不可能是正确的.例如,无论您尝试替换/查找/查找“ Hello”中的第一个“ l”还是第二个“ l”,它将始终替换第一个.

正确的方法是枚举.例如:

for idx, i in enumerate(strng):
    smallerStr = strng[:idx] + strng[idx+1:]

在这种特殊情况下,这并不重要,因为您实际上并不关心要删除第一个l还是第二个l.但是,只有仔细考虑并确保正确无误后,您才可以依靠它,并且可以添加注释以解释其正确性.通常,不要这样做.

上一篇:独特的排列生成器?


下一篇:Codeforces 1294E Obtain a Permutation(思维)