慢速CPU的快速索引?

Posted

技术标签:

【中文标题】慢速CPU的快速索引?【英文标题】:fast indexing for slow cpu? 【发布时间】:2013-09-06 09:50:35 【问题描述】:

我有一个大型文档,我想建立一个用于单词搜索的索引。 (我听说这种类型的数组真的被称为索引)。目前大约需要 10 分钟。有没有快速的方法呢?目前我遍历每个段落,如果我找到一个我以前没有遇到过的单词,我也将它添加到我的单词数组中,以及辅助数组中的段落编号,每当我再次遇到同一个单词时,我添加段落编号到索引。 :

associativeArray=chocolate:[10,30,35,200,50001],parsnips:[5,500,100403]

这需要很长时间,嗯,5 分钟左右。我尝试将此数组转换为字符串,但它太大了,即使在删除停用词后也无法包含在程序文件中,并且无论如何都需要一段时间才能转换回数组。

除了线性蛮力之外,还有更快的方法来构建文本索引吗?我不是在寻找可以为我做索引的产品,只是最快的已知算法。索引要准确,不模糊,不需要部分搜索。

【问题讨论】:

你使用什么语言? ejohn.org/blog/javascript-trie-performance-analysis 以下所有好的答案,在我全部测试之前不确定哪个是最好的。 我会选择 Trie 解决方案。 【参考方案1】:

我认为最好的办法是构建一个trie,在您的文本中添加一个单词,并为每个叶子设置一个您可以找到该单词的位置列表。

这不仅会为您节省一些空间,因为存储具有相似前缀的单词将需要更少的空间,而且搜索也会更快。搜索时间是 O(M),其中 M 是最大字符串长度,插入时间是 O(n),其中 n 是您要插入的键的长度。

由于显而易见的替代方案是哈希表,here 您可以找到两者之间的更多比较。

【讨论】:

【参考方案2】:

我会使用HashMap<String, List<Occurrency>> 这样你可以检查一个单词是否已经在大约O(1) 的yoz 索引中。

最后,当您收集了所有单词并希望经常搜索它们时,您可能会尝试找到一个没有或几乎没有冲突的哈希函数。这样,您可以保证 O(1) 的搜索时间(如果仍然有一些冲突,则几乎是 O(1))。

【讨论】:

【参考方案3】:

嗯,除了同意MrSmith42 建议使用内置HashMap 之外,我还想知道您花了多少时间跟踪段落编号?

改为跟踪行号会更快吗? (特别是如果您正在逐行读取输入)。

【讨论】:

【参考方案4】:

您的问题中有一些不清楚的地方,例如“我尝试将此数组转换为字符串,但它太大了,即使在删除 stop 之后也无法包含在程序文件中,这是什么意思的话,无论如何都需要一段时间才能转换回数组。”?!什么数组,你的输入是以段落数组的形式出现的,还是你的意思是每个单词的索引条目,或者什么。

也不清楚为什么你的程序这么慢,可能那里效率低下 - 我怀疑你检查“如果我找到一个我以前没有遇到过的单词” - 我假设你在字典中查找这个单词并且然后遍历出现的数组以查看是否有段落#?那是缓慢的线性搜索,您最好在那里使用set(想想您只关心键的哈希/字典),有点

concord = 
    'chocolate': 10:1, 30:1, 35:1, 200:1, 50001:1, 
    'parsnips': 5:1, 500:1, 100403:1  

然后您的支票变成if paraNum in concord[word]: ...,而不是循环或二分搜索。

PS。实际上假设您在数组中保留出现的列表并从第一段到最后一段扫描文本,这意味着数组将形成排序,因此您只需要检查最后一个元素if word in concord and paraNum == concord[word][-1]:。 (示例是伪代码/python,但您可以翻译成您的语言)

【讨论】:

以上是关于慢速CPU的快速索引?的主要内容,如果未能解决你的问题,请参考以下文章

5.索引简介

MySQL 索引总结

具有许多索引的表的慢速批量插入

多键索引上的慢速范围查询

我应该为这个慢速多连接查询添加哪些索引?

MySQL索引