我正在处理一个大型项目,这里不再赘述。这个项目中的一部分是从一份非常庞大的文本文档(至少约有50,000个单词(不重复))中提取每个唯一单词,并按使用频率从高到低进行排序(前三个可能是“a”、“an”和“the”)。
我的问题当然是,哪种排序算法最好?我看过计数排序,我很喜欢它,但我担心值的范围相对于唯一单词的数量来说太大了。
您有什么建议吗?
我的问题当然是,哪种排序算法最好?我看过计数排序,我很喜欢它,但我担心值的范围相对于唯一单词的数量来说太大了。
您有什么建议吗?
首先,您需要一个单词 -> 数量的映射表。 50000个词不多,可以轻松地放在内存中,所以没有什么可担心的。在C++中,您可以使用标准STL std :: map。
然后,一旦您有了映射表,就可以将所有映射表键复制到向量中。
接下来,使用自定义比较运算符对此向量进行排序:而不是比较单词,请比较映射表中的数量。(不要担心具体的排序算法-您的数组不是很大,因此任何标准库排序都适用于您。)
请查看链接。以图像方式呈现了不同算法的工作原理,这将给你一些提示!
假设两个单词出现的次数相同,那么你可以比快速排序获得更好的性能,只要无论以哪种顺序输出它们都没有关系。
第一步:创建一个哈希映射,将单词作为键值,频率作为相关值。在解析文件时,您将填充此哈希映射。在执行此操作时,请确保跟踪遇到的最高频率。此步骤的复杂度为O(n)。
第二步:创建一个列表,其条目数等于第一步中的最高频率。此列表中每个插槽的索引将保存具有与索引相等的频率计数的单词列表。例如,文档中出现3次的单词将进入list[3]。遍历哈希映射并将单词插入列表中的适当位置。此步骤的复杂度为O(n)。
第三步:反向遍历列表并输出所有单词。此步骤的复杂度为O(n)。
总体而言,此算法将在O(n)时间内完成您的任务,而不是快速排序所需的O(nlogn)。
n^2/2^p
。但没有详细说明如何实现。 - arunmoezhi我认为你想要做的事情可以参考下面的帖子:
http://karephul.blogspot.com/2008/12/groovy-closures.html
支持闭包的语言会使解决方案更加容易,正如Eric所提到的LINQ一样。
对于大型数据集,您可以使用信息检索中所谓的“基于排序的索引”,但对于50,000个单词,您可以采用以下方法: