我有一个大文档,我想建立一个单词搜索索引。 (我听说这种类型的数组实际上称为一致性)。目前大约需要10分钟。有快速的方法吗?目前我遍历每个段落,如果我找到一个我之前没有遇到过的单词,我将它添加到我的单词数组,以及子数组中的段落编号,每当我再次遇到相同的单词时,我添加段落编号到索引。 :
associativeArray={chocolate:[10,30,35,200,50001],parsnips:[5,500,100403]}
这需要永远,好吧,5分钟左右。我尝试将这个数组转换为一个字符串,但是它太大了,即使在删除了停用词之后也无法包含在程序文件中,并且无论如何都需要一段时间才能转换回数组。
除了线性暴力之外,还有更快的方法来构建文本索引吗?我没有找到能为我做索引的产品,只是最快的已知算法。索引应该准确,而不是模糊,并且不需要部分搜索。
答案 0 :(得分:2)
我认为最好的想法是建立一个trie,在文字的时候添加一个单词,并为每个叶子提供一个位置列表,您可以找到该单词。
这不仅可以节省一些空间,因为存储具有相似前缀的单词将需要更少的空间,但搜索也会更快。搜索时间为O(M),其中M是最大字符串长度,插入时间是O(n),其中n是要插入的键的长度。
由于显而易见的替代方法是哈希表here,您可以在两者之间找到更多的比较。
答案 1 :(得分:1)
我会使用HashMap<String, List<Occurrency>>
通过这种方式,您可以检查关于 O(1)的yoz索引中是否已有单词。
最后,当你收集了所有单词并想要经常搜索它们时,你可能会尝试找到一个没有碰撞或几乎没有碰撞的哈希函数。通过这种方式,您可以保证 O(1)时间进行搜索(如果仍有一些碰撞,则可以保证接近O(1))。
答案 2 :(得分:1)
那么,除了赞同MrSmith42关于使用内置HashMap
的建议外,我还想知道您花了多少时间跟踪段落编号?
更改内容以跟踪行号会更快吗? (特别是如果你逐行阅读输入)。
答案 3 :(得分:0)
你的问题中有一些不清楚的地方,比如你在“我尝试将这个数组转换为一个字符串”中的意思是什么,但它太大了,即使在删除停止之后它也无法包含在程序文件中无论如何,还需要一段时间才能转换回阵列。“?!什么数组,是你的段落数组形式的输入,或者你的意思是每个单词的索引条目,或者是什么。
目前还不清楚为什么你的程序如此缓慢,可能会有一些效率低下的东西 - 我怀疑你是否检查“如果我找到一个我之前没有遇到过的词” - 我认为你在字典中查找单词并且然后遍历出现的数组以查看段落#是否存在?那是慢线性搜索,你最好在那里使用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。实际上假设您保留数组中出现的列表并从第1段到最后一段扫描文本,这意味着数组将形成排序,因此您只需要检查那里的最后一个元素if word in concord and paraNum == concord[word][-1]:
。 (例子是伪代码/ python,但你可以翻译成你的语言)