[算法]大文本文件中找詞頻最高的10個詞


問題描述:一個大的英文文本,找到其中出現次數最高的10個單詞

思路:

 大文本文件肯定是一邊讀入一邊統計,並且要去掉標點符號,以空白分離單詞。

 要找高頻詞匯,肯定是要所有的單詞都要遍歷一次的,關鍵就是怎么遍歷了。為了時間效率高一點,可以采用類似二叉排序樹的方法,單詞以字母為序,比如abc排在edf前面,也排在acd前面。

每讀入一個詞就進行二叉樹排序樹的查找操作,找到了節點的統計字段加1,找不到插入。其次,還要維護大小為10數組存儲當前出現次數最高的詞和它們的出現次數,按降序排列。每在二叉排序樹中成功查找到該次,更新該詞的出現次數后,與前10數組進行比較,如果這個詞已經出現前10數組那就直接更新對應的值,如果這個詞沒有出現,則刪除最有一個,然后插入。

偽代碼:

先定義幾個數據結構:

typedef struct{

int count=0;    //統計出現次數

string content='';  //單詞的拼寫

} word;

typedef struct{    //二叉排序樹的一個節點的結構

word node:null;   //單詞的統計

biNode *left:null;  //左孩子

biNode *right:null; //右孩子 

} biTNode,*biTree;

word topTenWord[1..10] ;  //記錄當前出現次數最高的10單詞,按照從高到低排序,初始每個元素內容為word{null,0};

假設二叉樹的查找算法search已經實現,查找成功更新詞的出現次數不成功插入,返回插入的點或是找到的點。

算法

word[10] Count(filename){

//輸入:文件的名稱

//輸出:前十的詞頻的數組

binaryTree=createBinaryTree();   //先建立一個二叉排序樹

totalWordCount=0;  //文章里面的單詞數

firstWorld= readfrom(filename);

topTenWord[1]={firstWorld,1};   //先把第一個詞讀入,這樣可以避免越界檢查

 while(oneword=readfrom(filename)){  //讀入詞

     totalWordCount++; 

   biTNode *p=search(bianryTree,oneworld); 

     if (p.node.count>topTenWord.last.count) {     //新詞的出現次數比前10數組里面最小的出現次數大

       //從后往前找,找到第一個比它大或者等於它的

      i=10; 

       while(topTenWord[i].count<p.node.count) i--;   //不用判斷越界,因為不會越界,i最多走到1.

       if (topTenWord[i].content==p.node.content){  //同一個詞 

        topTenWord[i].count++;

      }

      else{

         for(j=9;j>i;j--){

          topTenWord[j+1]=topTenWord[j]; 

        } 

        topTenWord[i+1]=p.node;  //將當前單詞復制過來,復制內容,不是復制指針

      } 

   } 

 //計算頻率

for (i=1;i<=10;i++) {

 topTenWord[i]=topTenWord[i]/totalWordCount;

return topTenWorld; 

 

時間效率應該是nlog(n). 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM