有效地找到一个单词的所有可能的唯一排列

时间:2019-01-08 19:46:17

标签: python algorithm math combinatorics discrete-mathematics

让我们说以下单词:“ aabb”,那么所有可能的唯一排列是:“ aabb”,“ abab”,“ baba”,“ abba”,“ baab”和“ bbaa”。请注意,这里没有4个! = 24种方法,但4种选择2 =6。我目前有一个幼稚的方法:查找所有排列,包括重复项,然后删除重复项:

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

print(set(permutations("aabb")))

我的问题是,它们是否存在找到所有这些排列的更有效方法?

编辑:我不希望采用一种方法,该方法遵循的效率低下的想法是找到所有排列,然后删除重复项。我的代码示例已经做到了!

编辑:coldspeed正确地将我的问题标记为重复。正确的答案是使用sympy的multiset_permutations函数:

>>> from sympy.utilities.iterables import multiset_permutations
>>> list(multiset_permutations([1,1,1]))
[[1, 1, 1]]
>>> list(multiset_permutations([1,1,2]))
[[1, 1, 2], [1, 2, 1], [2, 1, 1]]

,根据@Bill Bell。

2 个答案:

答案 0 :(得分:0)

您可以使用permutations中的itertoolsset返回唯一的元素,然后使用join将字符串作为单个元素获取。下面是执行列表理解的方法。

from itertools import permutations
result = [''.join(lst) for lst in set((permutations("aabb")))]
print (result)

输出

['aabb', 'baba', 'bbaa', 'abab', 'abba', 'baab']

答案 1 :(得分:0)

可以使用permutationsset()删除重复项

from itertools import permutations
res=set()
for i in permutations('aabb'):
    res.add(i)

输出

set([('b', 'a', 'b', 'a'), ('b', 'b', 'a', 'a'), ('a', 'b', 'b', 'a'), ('a', 'a', 'b', 'b'), ('b', 'a', 'a', 'b'), ('a', 'b', 'a', 'b')])

如果希望得到字符串列表

map(''.join,set(permutations('aabb')))

输出

['baba', 'bbaa', 'abba', 'aabb', 'baab', 'abab']