(目前这是相当假设的,所以我没有太多细节可供提供。)
我有一个随机(英文)单词的平面文件,每行一个。我需要编写一个有效的程序来计算每个单词的出现次数。文件很大(可能大约1GB),但我有足够的RAM用于一切。它们存储在永久性介质上,因此读取速度很慢,所以我需要线性地读取它。
我的两个不受欢迎的想法是使用带有单词=>的哈希值。没有。事件的发生,或者与否的发生。在末端节点发生的事件。我有足够的RAM用于哈希数组,但我认为trie会有更快或更快的查找。
哪种方法最好?
答案 0 :(得分:2)
我使用一个Dictionary对象,其中键被转换为小写,值是计数。如果字典不包含该单词,请将其添加为值1.如果它确实包含该单词,则递增该值。
答案 1 :(得分:2)
鉴于阅读速度缓慢,可能不会产生明显的差异。无论如何,总时间将由读取数据的时间完全控制,因此这是您应该优化的工作。对于内存中的算法(主要是数据结构),只需使用您认为最舒适的语言中最方便的任何内容。
答案 2 :(得分:2)
哈希表是(如果做得正确,你说你有很多RAM)O(1)来计算一个特定的单词,而trie将是O(n)其中n是单词的长度。
使用足够大的哈希空间,您可以从哈希表中获得比从托管表中获得更好的性能。
答案 3 :(得分:2)
我认为计数为叶子的特里可以更快。
任何体面的哈希表实现都需要完全读取单词,使用哈希函数处理它,最后在表格中查找。
可以实现trie,以便在您阅读单词时进行搜索。这样,一旦你建立了唯一的单词前缀,你就会经常发现自己会跳过字符,而不是对单词进行全面查找。
例如,如果你读过字符:“torto”,trie会知道以这种方式开始的唯一可能的词是乌龟。
如果您可以比散列算法更快地执行此内联搜索更快的单词搜索,那么您应该能够更快。
然而,这是完全矫枉过正的。我絮絮叨叨,因为你说这纯粹是假设,我认为你想要一个假设的答案。使用最可维护的解决方案,在合理的时间内执行任务。微优化通常会浪费更多的工时,而不是节省CPU时间。
答案 4 :(得分:1)
我认为对你的用例来说,trie是过度的。一个哈希值=>发生次数正是我要使用的。即使使用像Perl这样的慢速解释语言,您也可以在几分钟内以这种方式使用1GB文件。 (我以前做过这个。)
答案 5 :(得分:1)
我有足够的内存用于哈希数组,但我认为trie会有更快或更快的查找。
此代码运行多少次?如果你只是做了一次,我会说优化你的时间而不是你的CPU的时间,并且做任何最快的实现(在合理范围内)。如果您有一个实现键值接口的标准库函数,那就使用它。
如果您多次执行此操作,请抓取数据文件的子集(或多个子集),并对您的选项进行基准测试。在不了解您的数据集的情况下,推荐一个在另一个上面是不确定的。
答案 6 :(得分:0)
一个简单的python脚本:
import collections
f = file('words.txt')
counts = collections.defaultdict(int)
for line in f:
counts[line.strip()] +=1
print "\n".join("%s: %d" % (word, count) for (word, count) in counts.iteritems())
答案 7 :(得分:0)
使用Python!
在询问它是否在哈希表中之前,逐行添加这些元素到set数据类型。如果您知道它在集合中,则添加字典值2,因为您之前已将其添加到集合中。
这将使一些内存和计算远离每次询问字典,而是更好地处理唯一有价值的单词,在调用结束时只是将所有不在字典中的单词转出设置值为1.(将两个集合相对于集合相交)
答案 8 :(得分:0)
在很大程度上,它取决于您在捕获数据后想要对数据执行的操作。见Why Use a Hash Table over a Trie (Prefix Tree)?