Python暴力枚举组合,给定一个起始字符串。

3

我正在尝试使用Python编写暴力字符串生成器,itertools.combinations_with_replacement 看起来就是个好选择。

gen = itertools.combinations_with_replacement('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',12)
for combination in gen:
  check(''.join(combination))

假设用户运行程序数小时,到达字符串aaaeabdouzIU

如果给定一个字符串,用户离开的地方开始制作组合,有没有办法做到这一点?

因此,如果我传递字符串'acc',它应该开始尝试'acd','ace',...

itertools.combinations_with_replacement不提供这个功能,有没有办法实现这个功能?


我不知道有什么方法,但是itertools文档列出了一段等效的代码(实际上有两段),你可以尝试将其应用到你的使用场景中。 - user707650
1
还有一个小技巧。如果您不想输入所有字母,请使用以下代码:import string; string.ascii_letters - cr1msonB1ade
你想要能够通过“递增”第一个输出来得到第二个,通过第n个来得到第n+1个。但是没有内置的方法可以实现这一点。尝试将输出范围转换为整数范围,然后再转回去。如果可能的话,你可以轻松地从序列中的任何位置开始递增整数,并生成任何子序列。 - krethika
2个回答

4
itertools官方文档页面获取原始代码,复制combinations_with_replacement代码,并将第7行替换为以您输入的单词作为起始索引的新索引。
inputStr='acc'
indices=[pool.index(l) for l in inputStr]

然后按照手册中的剩余代码运行。

编辑:完整可运行的函数如下:

def combinations_with_replacement(iterable, r, startWord=None):
    # combinations_with_replacement('ABC', 2) --> AA AB AC BB BC CC                                                                                   
    pool = tuple(iterable)
    n = len(pool)
    if not n and r:
        return
    if startWord is None:
        indices = [0] * r
    else:
        assert len(startWord) == r
        indices = [pool.index(l) for l in startWord]
    yield tuple(pool[i] for i in indices)
    while True:
        for i in reversed(range(r)):
            if indices[i] != n - 1:
                break
        else:
            return
        indices[i:] = [indices[i] + 1] * (r - i)
        yield tuple(pool[i] for i in indices)

最后的else块应该是无意的 - 它属于for循环,而不是if语句。否则代码将无法正常工作。 - Magnus

1
如果你知道如何生成下一个组合,那么这很容易。
其中一种方法是定义一个从组合到自然数的映射,以及一个从自然数到组合的逆映射。例如,您可以使用 Base 62 conversion 中的 base62_encode/base62_decode。
def next_comb(s):
    return base62_encode(1+base62_decode(s))

还需要一个生成器来生成所有给定起始点的组合:

def generate_all(start='a'):
    while True:
        yield start
        start = next_comb(start)

使用方法:

for comb in generate_all():
    print(comb)

或者,从起始点恢复计算:
for comb in generate_all(starting_point):
    print(comb)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接