找出文件中最高频率的前k个单词

很久之前参加一个小公司实习的线下笔试,做了这个题目,感觉还蛮有意思的。想做个记录。


一、题目

Write a program for displaying the ten most frequent words in a file such that your program should be efficient in all complexity measures.

问题的关键在于,文件的单词量很大很大的话,如何有效的进行统计呢。



二、解题思路


1.  首先逐个单词读进来放入到buffer中。


2. 然后是建立单词查找树。


用结构体定义树的节点TrieNode,主要成员:

bool isEnd; //表示是否是一个单词的结尾

int frequency;  //表示单词的频率(如果是一个单词结尾的话)

int inTable; //表示是否在高频词汇记录表中以及在表中第几个位置,可以用0表示不在表中,1~k表示在某一位置,方便更新记录表的数据

TrieNode* child[26]; //指向单词当前字母的下一个字母


这部分也是这个算法的重要部分,一个好的建立树的方法能有效利用空间,简单的Hash表映射明显开销更大。


3.然后是前k个高频词汇的记录表。

可以用vector或struct 来记录。记录前k个单词,以及其频率。以及每个单词需要一个指针指向单词查找树中相应的末尾节点,因为如果该单词被淘汰出记录表后,需要将查找树节点中的 inTable置0。

另外还需要用一个(int) minFrequency记录表的最低频率,和(stack) minTable记录最低频单词的位置。

这部分的关键是考虑好如何更高效的把新单词更新入记录表。

主要有以下几种情况:

a. 单词本身在记录表中,则更新频率。

b. 单词不在记录表中,当记录表未满时,则直接吧单词加入记录表中。

c. 单词不在记录表中,记录表满了,则判断该词的频率是否大于记录表的最低频率。如果是,则替换记录表中的单词,并将旧单词弹出minTable,如果minTable中的元素个数为1,还需要更新最低频的频率,并遍历记录表,重新记录该频率的单词的位置。


三、后续思考

1. 感觉更新记录表这部分的算法还应该重新考虑,并分析算法的效率。

2. 这个算法还有个不好的地方是,题目是求前k个高频词,如果最低频的单词有并列的,则只能保留一部分,而有可能淘汰,漏掉一部分。


你可能感兴趣的:(data,structure)