我有一个大文本文件(1.5 Gb),有1亿个字符串(没有重复的字符串),所有字符串都在文件中逐行排列。 我想用Java制作一个WEP应用程序,以便当用户给出一个关键字(子字符串)时,他会得到包含该关键字的文件中存在的所有字符串的计数。 我已经知道一种技术LUCENE..还有其他方法可以做到这一点吗??我希望在 3-4 秒内获得结果。我的系统有4GB RAM和双核配置。需要在"仅限 JAVA"中执行此操作
尝试使用哈希表。可以做的还有一件事是任何类似于MAP-REDUCE的方法。我想说的是,您可以尝试使用倒排索引。谷歌使用相同的技术。您可以创建一个停用词文件,您可以在其中放置可以忽略的单词,例如 I、am、the、a、an、in、on 等。
这是我认为唯一可能的事情。我在某处读到,为了搜索,你可以数组。
您的关键字中是否有很多重叠?如果是这样,您也许能够存储从关键字 ( String
) 到文件位置 ( ArrayList
的哈希映射。尽管对象开销,但不能将所有行都存储在内存中。
获得文件位置后,可以在文本文件中查找该位置,然后在附近查找以获取括起来的换行符,返回该行。那肯定不到 4 秒。这里有一些信息。如果这只是为了做一点锻炼,那就行不通了。
更好的解决方案是两层索引,一个将关键字映射到行号,然后另一个将行号映射到行文本。这不适合您计算机上的内存。有很棒的基于磁盘的键值存储,尽管效果很好。如果这不仅仅是玩具问题,请选择Reddis路线。
您可以根据每个单词的前几个字母构建目录结构。 例如:
/A
/A/AA
/A/AB
/A/AC
...
/Z/ZU
在该结构下,您可以保留一个包含所有字符串的文件,其中第一个字符与文件夹名称匹配。 搜索词中的第一个字符会将选择范围缩小到包含整个列表一小部分的文件夹。 从那里,您可以仅对该文件进行全面搜索。 如果速度太慢,请增加目录树的深度以覆盖更多字母。
由于您的 RAM 多于文件大小,因此您可以将整个数据存储为 RAM 中的结构并非常快速地搜索它。trie 可能是一个很好的数据结构;它确实具有快速前缀查找功能,但不确定它对子字符串的性能如何。