自動提取文章摘要AutoSummary

  在文本搜索引擎項目中,須要對已排序的文章進行摘要提取,而後與標題,路徑一塊兒封裝成Json數據返回客戶端。所以這裏我本身寫一個自動摘要,來大概完成這個任務。在自動摘要提取過程當中,使用了一個分詞庫:CppJieba分詞庫。所以在頭文件中包含了頭文件 「Application.hpp」。html

思路:ios

  一、對文章提取關鍵字。一般,關鍵字可以表明這篇文章的所描述的內容。所以使用CppJieba分詞庫中「Application.hpp」中api  extract()進行關鍵字提取。我提取的是前50個,若文章關鍵字不夠50個則取實際個數。關鍵字的結果已經按照權重的順序排序好。api

  二、把文章拆分紅句子。這裏是只對中文進行處理(英文道理也同樣),當遇到句號‘  。’,問號‘ ? ’,感嘆號‘ ! ’,算一句話。把每一句話按順序保存到vector<string>類型的數組sentences中。數組

  三、遍歷關鍵字數組,對每個關鍵字在每個句子中查找包含該關鍵字的第一個句子,並把該句子加入到vector<string>類型的數組summary中。app

  四、若遍歷到達關鍵字上限或者句子數量到達上限,跳出循環。函數

  五、將數組summary中的句子按順序拼接從摘要。搜索引擎

代碼以下:spa

  1 #ifndef _AUTOSUMMERY_HPP
  2 #define _AUTOSUMMERY_HPP
  3 #include"../src/Statistics/src/Application.hpp"
  4 #include <string>
  5 #include<set>
  6 #include <utility>
  7 #include<vector>
  8 #include<iostream>
  9 #include<functional>
 10 using namespace std;
 11 using namespace CppJieba;
 12 class AutoSummary
 13 {
 14     public:
 15         AutoSummary(Application &app,int maxSentenceNum=10)//初始化一個自動摘要對象
 16             :maxSentenceNum_(maxSentenceNum),
 17             app_(app)
 18         {}
 19 
 20         //自動提取摘要
 21         string summarizer(string & originTxt,int KEYNUM=50) 
 22         {
 23             vector<pair<string,double> > keywords;
 24             app_.extract(originTxt,keywords,KEYNUM);    //取文章的前50個關鍵詞,按權重排序
 25             vector<string> sentences;            //裝載句子的數組
 26             getSentences(originTxt,sentences);        //把文章拆分紅句子
 27             int sentencesNum = sentences.size();        //句子的數量
 28             vector<string> summaryRet;                    //裝包含關鍵字的句子
 29             set<int> summarySet;                        //句子去重
 30             set<int>::iterator it;
 31             KEYNUM = keywords.size();//若是關鍵字數量小於50則取實際的數量
 32             for(int i = 0;i<KEYNUM;i++)
 33             {
 34                 for(int j = 0;j<sentencesNum;j++)
 35                 {
 36                     int pos = sentences[j].find(keywords[i].first,0);
 37                     if(pos!=string::npos)
 38                     {
 39                         it = summarySet.find(pos);
 40                         if(it==summarySet.end())
 41                         {
 42                             summaryRet.push_back(sentences[j]);//向數組添加句子
 43                             summarySet.insert(j);            
 44                             break;    //跳出循環,找下一個關鍵字
 45                         }
 46                     }
 47                 }
 48                 //跳出循環的條件
 49                 if(summaryRet.size()>maxSentenceNum_||summaryRet.size()>=sentencesNum)    
 50                     break;
 51             }
 52             string summaryStr;
 53             int i = 0;
 54             int num  = summaryRet.size();
 55             while(i<num)
 56             {
 57                 summaryStr = summaryStr + sentences[i]+"……";
 58                 i++;
 59             }
 60 
 61             return summaryStr;
 62         }
 63 
 64     private:
 65         //將文章拆分紅句子,私有成員函數,在summarizer()中調用
 66         void getSentences(const string &originTxt,vector<string> &sentenceVec)
 67         {
 68             int beg=0,end=0,pos=0,pos1=0;
 69             int txtSize = originTxt.size();
 70             while(beg<txtSize&&pos!=string::npos)
 71             {
 72                 if((pos=originTxt.find("",beg))!=string::npos)
 73                 {
 74                     if((pos1=originTxt.find("",beg))!=string::npos)
 75                     {
 76                         pos=((pos<pos1)?pos:pos1);
 77                         if((pos1=originTxt.find("",beg))!=string::npos)
 78                         {
 79                             pos=((pos<pos1)?pos:pos1);
 80                         }
 81 
 82                     }
 83                     else if((pos1=originTxt.find("",beg))!=string::npos)
 84                     {
 85                         pos=((pos<pos1)?pos:pos1);
 86                     }
 87                 }
 88                 else if((pos=originTxt.find("",beg))!=string::npos)
 89                 {
 90                     if((pos1=originTxt.find("",beg))!=string::npos)
 91                     {
 92                         pos=((pos<pos1)?pos:pos1);
 93                     }
 94 
 95                 }
 96                 else if((pos1=originTxt.find("",beg))!=string::npos)
 97                 {
 98                     pos = pos1;
 99                 }
100                 else
101                 {
102                     break;
103                 }
104                 if(pos!=-1)
105                 {
106                     int len = pos-beg;
107                     string sentence(originTxt.substr(beg,len));
108                     sentenceVec.push_back(sentence);
109                     beg = pos+3;
110                 }
111             }
112         }
113 
114     private:
115         Application & app_;//分詞庫的引用
116         int maxSentenceNum_;//摘要中的句子數目,由外部傳進。
117 };
118 #endif

 

參考:http://www.ruanyifeng.com/blog/2013/03/automatic_summarization.htmlcode

相關文章
相關標籤/搜索