当前位置: 首页 > 知识库问答 >
问题:

在文件内存使用中查找k个最常见的单词

俞新翰
2023-03-14

假设你得到了一个巨大的文件,比如1GB。该文件每行包含一个单词(总共n个单词),您希望在该文件中找到k个最常见的术语。

现在,假设您有足够的内存来存储这些单词,那么在减少内存使用量和Big-O复杂性中的恒定开销方面,什么是更好的解决问题的方法?我相信有两种基本算法可以使用:

  1. 使用一个哈希表和一个最小堆来存储出现的次数和前K个单词。这是O(n nlogk)~O(n)
  2. 使用trie存储单词和出现的次数,然后遍历trie以计算最频繁的单词。这是O(n*p)~O(n),其中p是最长单词的长度

哪种方法更好?

另外:如果您没有足够的内存用于哈希表/trie(即10MB左右的有限内存),那么最好的方法是什么?

共有3个答案

葛霄
2023-03-14

您是否开车去存储中间结果?如果为真:

你可能有一些元结构。和一组哈希表。读取一部分数据(而散列数据的大小

描述你的哈希表。在meta中,您可以存储唯一单词的数量和此哈希中所有单词的计数以及一个世界的最大计数!!!我

在这之后。您可以从磁盘加载哈希表并合并。

例如,您可以按唯一单词的升序加载哈希表,或按哈希中一个世界的最大计数加载哈希表。在这一步中,您可以使用一些启发式方法。

束新
2023-03-14

对于有限内存选项,您可以先对列表进行快速排序,然后简单地用k个项目填充一个哈希表。然后,您还需要一个计数器来知道您正在检查当前单词中有多少项-如果它更高,则用当前项替换哈希表中最低的项。

这可能对初始列表有效,但比只扫描完整列表并用计数填充哈希表要慢。

鄂慈
2023-03-14

关于常数,哪个更有效是非常依赖的。一方面,trie为插入所有元素提供了严格的O(N)时间复杂度,而哈希表在最坏的情况下可能会退化为二次时间
另一方面,当涉及到缓存时,尝试并不是非常有效-每个搜索都需要O(| S |)随机访问内存请求,这可能会导致性能显著下降。

这两种方法都是有效的,我认为在选择其中一种时应该考虑多种因素,比如最大延迟(如果是实时系统)、吞吐量和开发时间。

如果平均案例性能是最重要的,我建议生成一堆文件并运行统计分析哪种方法更好。威尔科克森签名检验是目前使用的最先进的假设检验。

关于嵌入式系统:这两种方法仍然有效,但是在这里:trie中的每个节点(或一堆节点)将在磁盘上,而不是在RAM上。注意,这意味着对于trie O(|S|)随机访问磁盘寻求每个条目,这可能是慢的。

对于哈希解决方案,您有10MB,假设他们可以将其中的5MB用于磁盘指针的哈希表。让我们也假设你可以在这5MB上存储500个不同的磁盘地址(这里是悲观分析),这意味着你在每次哈希搜索后还有5MB要加载一个桶,如果你有500个桶,负载因子为0.5,这意味着你可以存储500*5MB*0.5~=1.25GB

注意,如果仍然不够,我们可以重新刷新指针表,这与在虚拟内存机制中的分页表中所做的非常类似。

由此我们可以得出结论,对于嵌入式系统,哈希解决方案在大多数情况下更好(请注意,在最坏的情况下,它可能仍然存在高延迟,这里没有银弹)。

另外,基数树通常比trie更快、更紧凑,但与哈希表相比,trie的副作用相同(当然不太明显)。

 类似资料:
  • 问题内容: 我有看起来像这样的数据: 我想要一个函数,该函数根据我选择的movie_id返回注释中最常用的词。因此,如果我查询movie_id = 1,则会得到: 如果我查询movie_id = 2,则会得到: 我看到了一些使用tsql的解决方案,但我以前从未使用过,也不了解代码。寻找一种在sqlite3中做到这一点的方法。 问题答案: 您可以使用一个非常丑陋的查询来执行此操作。 这是未经测试的。

  • 问题内容: 我有一个具有以下结构的行表,其中每一行都有每个人喜欢的颜色和该人所属组的列表。我如何返回每个组中最常见的颜色的列表? 您可以组合设置重叠,获取交点然后进行其他计数和排名吗? 问题答案: 快速而肮脏: 一个更好 [`LATERAL JOIN`](http://www.postgresql.org/docs/current/interactive/sql-select.html) 在Pos

  • 问题内容: 在Python列表中查找最常见元素的有效方法是什么? 我的列表项可能无法散列,因此无法使用字典。同样在绘制的情况下,应返回索引最低的项目。例: 问题答案: 提出了这么多解决方案,令我惊讶的是没有人提出我认为显而易见的解决方案(对于不可哈希但可比较的元素)-。 提供快速,可重用的功能,并允许你将一些棘手的逻辑委托给经过良好测试的标准库组件。考虑例如: 当然,这可以写得更简洁一些,但我的目

  • 我想验证我的伪代码,建议优化和更好的方法。 mostRepeatingWords(int-rank): (此处的rank定义您要选择的级别,即前X个最重复的单词) > 创建一个新文件“wordCount”,其中包含如下条目 复杂性O(np),其中n是已排序页面的数量,p 是一个简单的函数,它将此元素与first和previous等进行比较,并确定单词的频率。 电话号码:500 电话:600 将合并

  • 问题内容: 我正在使用以下外壳程序脚本将一个文件的内容查找到另一个文件中: 我正在执行脚本,但未显示CSV文件中的内容。我的contents.txt文件还包含CSV文件中的数字,例如或。我的工作有什么问题吗? 问题答案: 本身能够做到。只需使用标志: 是每行包含一个模式的文件;并且是要在其中进行搜索的东西文件。 请注意,即使每行的内容看起来像一个正则表达式,也要强制将每行视为一个模式,您应该使用f

  • 问题内容: 假设我有一个具有属性X的表A,如何找到出现次数最多的X?(可以有多个出现次数最高的事件) 即表A 我想回来 我不能在Sqlite中使用关键字ALL,所以我很茫然。 我想到了获取每个X的计数,然后对其进行排序,然后以某种方式使用ORDER BY DESC,以使最大数位于顶部,然后与LIMIT进行比较,以检查第一个元组以下的值是否相等(这意味着它们只是一样),但我不确定LIMIT语法以及是