这种方法与其他答案相比不够优化,但可能足够好,并且实现简单。思路是将算法反转,而不是逐个测试每个子字符串与较大的字符串匹配,而是迭代大字符串并在每个位置测试可能匹配的子字符串,使用字典来缩小需要测试的子字符串数量。
输出将与原始代码不同,按索引升序排序而不是按子字符串排序,但如果您想要按子字符串排序,则可以对输出进行后处理。
创建一个包含以每个可能的1-3个字符开头的子字符串列表的字典。然后迭代字符串,在每个字符处读取其后的1-3个字符,并检查该位置上是否存在与以这些1-3个字符开头的字典中的每个子字符串匹配的内容:
string="some large text here"
sub_strings=["some", "text"]
dict = {}
for s in sub_strings:
if s[0:3] in dict:
dict[s[0:3]].append(s)
else:
dict[s[0:3]] = [s];
for i in range(0, len(string)):
for j in range(1,4):
char = string[i:i+j]
if char in dict:
for word in dict[char]:
if string[i:i+len(word)] == word:
print word, i
如果您不需要匹配任何长度为1或2个字符的子字符串,则可以摆脱for j
循环,并使用char = string[i:3]
直接分配字符。
使用这种第二种方法,我通过读取托尔斯泰的《战争与和平》并将其拆分为唯一单词来计时算法,如下所示:
with open ("warandpeace.txt", "r") as textfile:
string=textfile.read().replace('\n', '')
sub_strings=list(set(string.split()))
对文本中的每个唯一单词进行完整搜索并输出每个实例共花费了124秒。