【问题标题】:how to find all permutations of a given string in python? [duplicate]如何在python中找到给定字符串的所有排列? [复制]
【发布时间】:2019-11-06 16:44:09
【问题描述】:

我已经尝试过这种方法,但它出错了。那么,有什么想法可以解决这个问题吗?

def swap(seq, i , j):
    temp = 0
    temp = seq[i]
    seq[i] = seq[j]
    seq[j] = temp

def all_possible_strings(seq):
    list_of_results = []
    for i in range(len(seq)):
        for j in range(len(seq)):
            copy_of_seq = seq[:]

            swap(copy_of_seq, i ,j)

            list_of_results.append("".join(copy_of_seq))

    return list_of_results

这是输出: ['abc', 'bac', 'cba', 'bac', 'abc', 'acb', 'cba', 'acb', 'abc']

【问题讨论】:

  • 输出应该是什么?我建议您阅读 this article 以获取有关调试代码的提示。
  • 这应该是输出:['abc', 'acb', 'bac', 'bca', 'cab', 'cba']

标签: python string algorithm permutation


【解决方案1】:

您的算法不可能解释所有排列。

请注意,(i,j) 对可以是任何索引对。但是,对于代码中的每个排列,您从原始字符串开始并应用一次交换。这不可能让你得到所有的排列。

假设您以ABCD 开头。如果您想要反向排列 DCBA,您将无法在单个交换中执行此操作。一次交换最多会改变 2 个字符的位置,但所有 4 个字符需要在不同的位置。

请注意,大小为n 的列表的可能(i,j) 对数为n*n = n^2,与预期的排列数n! 不同。在几乎所有情况下,n! > n^2,这意味着肯定会缺少排列。

此外,您还有像 (1,1) 这样的对,这会导致什么都不做的交换(这很好,除了现在 (2,2)(3,3) 等给出重复的排列)[感谢 Code-Apprentice指出这一点]。您还拥有(1,2),这将导致ACBD,以及(2,1),这也会导致ACBD。这就是为什么您的最终排列列表中有重复排列的原因。

附:在 Python 中,您只需执行 a,b = b,a 即可交换两个元素。


堆的算法

正确的实现是使用Heap's algorithm 之类的东西,这是一种适当的、更复杂的元素切换以获得所有排列。

您不必每次都制作列表的新副本,而是继续在同一个列表上进行交换,它将循环遍历所有排列,前提是您按照算法指定的正确顺序进行操作。

我不会在这里详细介绍算法,因为资源可以很好地解释它。如果你真的需要一个明确的 Python 实现示例,那也是 easy to find

【讨论】:

  • 另外,与 (i,j)(1,1)(2,2) 交换将产生相同的字符串。
【解决方案2】:

你可以使用itertools.permutations:

import itertools

seq = 'abc'
list_of_results = [''.join(p) for p in itertools.permutations(seq)]
print(list_of_results)

输出:

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

【讨论】:

  • 我想练习普通的解决方案只是为了掌握字符串排列的概念
  • @MohamedAbdElsatar,该线程还包括有关如何实现排列的链接。所以如果你落后于数学,你应该没问题。
猜你喜欢
  • 1970-01-01
  • 2017-05-26
  • 1970-01-01
  • 1970-01-01
  • 2011-05-13
  • 2019-03-29
  • 2012-04-20
  • 1970-01-01
相关资源
最近更新 更多