如何查找字符串和字母/数字的所有组合,例如: string = StackOverFlow 字母= Z. 组合:
SztackOverFlow
SztzackOverFlow
StzackOverFlow
依此类推......我想要所有的组合。
另一个例子:
string" Dumb"
信" Z"
组合:
DZumb
DZuZmb
DZuZmZb
DuZmZb
DumZb
我不想要这封信" Z"添加到字符串的末尾或前面" Dumb
我尝试过使用itertools,但我似乎无法用他们的文档弄明白。
我看到的所有解决方案都不是我想要的......它需要生成我在上面发布的组合..
答案 0 :(得分:4)
这是一个生成器,它使用itertools.product
来创建已填充和未填充的插槽的组合,然后将它们与单词的字母一起拉开。
from itertools import product
def inserted(word, ch):
n = len(word) - 1
last = word[-1]
patterns = product(('', ch), repeat=n)
# skip the initial empty string pattern
next(patterns)
for t in patterns:
yield ''.join([u+v for u,v in zip(word, t)]) + last
word = 'Dumb'
letter = 'Z'
for s in inserted(word, letter):
print(s)
<强>输出强>
DumZb
DuZmb
DuZmZb
DZumb
DZumZb
DZuZmb
DZuZmZb
只是为了好玩,这里基本上是相同的算法,但使用二进制计数而不是itertools.product
,因此不需要导入。
def inserted(word, ch):
n = len(word) - 1
last = word[-1]
t = ('', ch)
for i in range(1, 2**n):
yield ''.join([u + t[int(b)]
for b, u in zip('{:0{}b}'.format(i, n), word)]) + last
我认为你会同意我的第一个版本更容易阅读。 :)
答案 1 :(得分:2)
我认为这应该能满足你的需求:[我会尝试更多地优化它]
def combination(word, letter, start=1, end=-1):
if start >= end:
return [word]
else:
new_word = word[:start] + letter + word[start:]
output = [new_word, word]
output.extend(combination(new_word, letter, start+2, end+1))
output.extend(combination(word, letter, start+1, end))
return list(set(output))
输出:
combination('dumb', 'z', start=1, end=len('dumb'))
['dzuzmb', 'duzmb', 'dzuzmzb', 'dzumb', 'dzumzb', 'dumzb', 'dumb', 'duzmzb']
如果您不想在返回列表中使用原始单词,那么您可以使用此代码:
def combination(word, letter, start=1, end=-1):
if start >= end:
return []
else:
new_word = word[:start] + letter + word[start:]
output = [new_word]
output.extend(combination(new_word, letter, start+2, end+1))
output.extend(combination(word, letter, start+1, end))
return list(set(output))
说明:
递归的基础是:
if start is >= end: return [No place left to insert letter in word]
otherwise:
insert letter at start of the word and call the same method to work on this new word from inserted index +2.
*+2 because say at index 1 in dumb. We insert letter z as dzumd. Now we don't want to insert another z at dzzumb. So +2.*
also in the original word just pass it into recursion because we want to work on duzmb. where no z is inserted before u.