因此,作为练习,我正在构建一种算法,以便尽可能快地在较大的字符串中搜索单词(任意字符集)。由于几乎没有现有搜索算法的先前知识,到目前为止,我的方法如下:
这就是它的要点。我想我可以使用长字符的地图,但现在我只是使用对。
我能做些什么才能让它更快?我是以正确的方式接近这个吗?
答案 0 :(得分:2)
字符串搜索是一个经过深入研究的主题:
您正在考虑寻找例如连续2个字符并存储该组合的频率,即使您使用平衡数据结构,这也是一项非常昂贵的操作。我真的没有看到如何将连续字符存储为预处理步骤对您有所帮助。
因此,显然有许多用于字符串搜索的算法。我觉得有趣的是,有一些算法甚至不需要扫描文本体中的每个字符。示例:如果您搜索单词'abbbbbc'并且您发现字符'd'作为文本正文的下一个字符,您可以立即跳出5个字符而无需查看它们是什么,然后如果下一个字符是'b'或'c'你显然必须回去查看你是否在跳跃时犯了错误,但如果没有,那么你跳过超过5个字符而不需要进行比较。然而,这很难实现,并导致有限自动机理论。
答案 1 :(得分:0)
另一个答案是指Boyer Moore算法。它使用子字符串上的预处理,而不是搜索材料。它被认为是一种快速的非索引搜索。
还有其他搜索算法可用于多次搜索同一文档。考虑Aho-Corasick。
但是,我使用的与您描述的类似的算法在下面的Python中实现。我们的想法是,对于每个元素,获取它出现的一组索引。然后进行搜索,使用子字符串中最不常见的字符作为参考点列表。循环遍历每个参考点的子字符串,在找不到索引时断开。
你应该测试一下,看它是否比Boyer Moore或其他算法更快。这个可以改进。这将是一个很好的练习,迟到五年。
class IndexRegistry(object):
def __init__(self, iterable):
self._store = defaultdict(set)
for index, val in enumerate(iterable):
self._store[ val ].add( index )
def find(self, items):
_, refIndex, refItem = min(
[ ( len(self._store[item]), index, item )
for index, item in enumerate(items)
],
key=lambda el: el[0]
)
for referenceIndex in self._store[ refItem ]:
startIndex = referenceIndex - refIndex
for itemIndex, item in enumerate(items):
absIndex = startIndex + itemIndex
if absIndex not in self._store[ item ]:
break #substring broken
else: #no break
yield startIndex
def __contains__(self, items):
try:
next(self.find(items))
except StopIteration:
return False
return True