这是与许多类似的字符长的话很慢。与理论上的最大性能相比较慢。例如,permutations("mississippi")
将产生比必要更长的列表。这将有39916800的长度,但却集合的大小为34650.
>>> len(list(permutations("mississippi")))
39916800
>>> len(set(permutations("mississippi")))
34650
因此,与您的方法大缺陷就是你生成所有字谜,然后删除重复的。使用只生成唯一字母的方法。
编辑:
下面是一些工作,但非常难看,并可能bug的代码。当你阅读这篇文章时,我会更好。它确实给密西西比州34650,所以我认为没有任何重大错误。再次警告。丑陋!
# Returns a dictionary with letter count
# get_letter_list("mississippi") returns
# {'i':4, 'm':1, 'p': 2, 's':4}
def get_letter_list(word):
w = sorted(word)
c = 0
dd = {}
dd[w[0]]=1
for l in range(1,len(w)):
if w[l]==w[l-1]:
d[c]=d[c]+1
dd[w[l]]=dd[w[l]]+1
else:
c=c+1
d.append(1)
dd[w[l]]=1
return dd
def sum_dict(d):
s=0
for x in d:
s=s+d[x]
return s
# Recursively create the anagrams. It takes a letter list
# from the above function as an argument.
def create_anagrams(dd):
if sum_dict(dd)==1: # If there's only one letter left
for l in dd:
return l # Ugly hack, because I'm not used to dics
a = []
for l in dd:
if dd[l] != 0:
newdd=dict(dd)
newdd[l]=newdd[l]-1
if newdd[l]==0:
newdd.pop(l)
newl=create(newdd)
for x in newl:
a.append(str(l)+str(x))
return a
>>> print (len(create_anagrams(get_letter_list("mississippi"))))
34650
它的工作原理是这样的:对于每一个独特的字母l,创造一切的独特排列有字母L少了一个次数,然后追加L到所有这些排列。
对于“密西西比州”来说,这比设置(排列(单词))快得多,而且它远没有最佳书写。例如,字典非常慢,在这段代码中可能有很多事情要改进,但是它表明算法本身比你的方法快得多。
请参阅https://stackoverflow.com/questions/40752319/algorithm-to-list-unique-permutations-of-string-with-duplicate-letters/40756214 #40756214 –