我一直致力于快速有效地解决以下问题,但到目前为止,我只能使用相当慢的嵌套循环解决方案来解决它。无论如何,这里是描述:
所以我有一个长度为L的字符串,比方说'BBBX'
。我想找到所有可能的长度为L的字符串,从'BBBX'
开始,最多不同,最多2个位置,至少0个位置。最重要的是,在构建新字符串时,必须从特定字母中选择新字符。
我猜字母表的大小并不重要,所以在这种情况下我们可以说字母为['B', 'G', 'C', 'X']
。
因此,一些示例输出将是,'BGBG'
,'BGBC'
,'BBGX'
等。对于此示例,长度为4且最多包含2个替换的字符串,我的算法找到67可能的新字符串。
我一直在尝试使用itertools
来解决这个问题,但我在寻找解决方案时遇到了一些困难。我尝试使用itertools.combinations(range(4), 2)
找到所有可能的位置。我正在考虑使用product()
中的itertools
来构建所有可能性,但我不确定是否有一种方法可以将它以某种方式连接到{{1}的输出中的索引}。
答案 0 :(得分:2)
这是我的解决方案。
第一个for循环告诉我们将执行多少次替换。 (0,1或2 - 我们通过每个)
第二个循环告诉我们将改变哪些字母(按索引)。
第三个循环遍历这些索引的所有可能的字母更改。有一些逻辑可以确保我们实际更改字母(更改" C"到" C"不计算)。
import itertools
def generate_replacements(lo, hi, alphabet, text):
for count in range(lo, hi + 1):
for indexes in itertools.combinations(range(len(text)), count):
for letters in itertools.product(alphabet, repeat=count):
new_text = list(text)
actual_count = 0
for index, letter in zip(indexes, letters):
if new_text[index] == letter:
continue
new_text[index] = letter
actual_count += 1
if actual_count == count:
yield ''.join(new_text)
for text in generate_replacements(0, 2, 'BGCX', 'BBBX'):
print text
这是它的输出:
BBBX GBBX CBBX XBBX BGBX BCBX BXBX BBGX BBCX BBXX BBBB BBBG BBBC GGBX
GCBX GXBX CGBX CCBX CXBX XGBX XCBX XXBX GBGX GBCX GBXX CBGX CBCX CBXX
XBGX XBCX XBXX GBBB GBBG GBBC CBBB CBBG CBBC XBBB XBBG XBBC BGGX BGCX
BGXX BCGX BCCX BCXX BXGX BXCX BXXX BGBB BGBG BGBC BCBB BCBG BCBC BXBB
BXBG BXBC BBGB BBGG BBGC BBCB BBCG BBCC BBXB BBXG BBXC
答案 1 :(得分:1)
没有经过多少测试,但它确实找到了67个例子。将索引连接到产品的简便方法是通过zip()
:
def sub(s, alphabet, minsubs, maxsubs):
from itertools import combinations, product
origs = list(s)
alphabet = set(alphabet)
for nsubs in range(minsubs, maxsubs + 1):
for ix in combinations(range(len(s)), nsubs):
prods = [alphabet - set(origs[i]) for i in ix]
s = origs[:]
for newchars in product(*prods):
for i, char in zip(ix, newchars):
s[i] = char
yield "".join(s)
count = 0
for s in sub('BBBX', 'BGCX', 0, 2):
count += 1
print s
print count
注意:与FogleBird的主要区别在于我首先发布了 - LOL ;-)算法非常相似。我构建了product()
的输入,因此不会尝试替换自己的字母; FogleBird允许“身份”替换,但计算进行了多少次有效替换,然后在发生任何身份替换时抛弃结果。对于较长的单词和较多的替换,可以慢得多(可能是len(alphabet)**nsubs
循环(len(alphabet)-1)**nsubs
和... in product():
之间的差异。“ / p>