javascript和JQuery焦点图和代码特效大全
当前最流行的开源CMS网站系统大全
当前位置:首页 > 编程开发 > C语言C++

C++实现简单的分词功能

来源:IT技术网编辑:雨天发布于:2017-01-21人围观

 

C++实现简单的分词功能,具体代码如下:


  1. // word.cpp : Defines the entry point for the console application.
  2. //
  3.  
  4. #include "stdafx.h"
  5. // mympseg.cpp : 定义控制台应用程序的入口点。
  6. #include <iostream>
  7. #include <string>
  8. #include <list>
  9. #include <map>
  10. using namespace std;
  11.  
  12. const int NODENUM=100;//最大节点数
  13.  
  14. map <string,float> mapWord2Prob;
  15. const int MaxWordLength=8;//词的最大长度
  16. const int MinWordLength=2;//词的最小长度
  17. float prob[NODENUM];//每个节点的最大累计概率
  18. int prevNode[NODENUM];//每个节点的最优前趋节点
  19. const string strDelimiter=" ";//分词分割符
  20. void LoadDict()
  21. {
  22. mapWord2Prob["有"]=0.018;
  23. mapWord2Prob["有意"]=0.0005;
  24. mapWord2Prob["意见"]=0.001;
  25. mapWord2Prob["见"]=0.0002;
  26. mapWord2Prob["分歧"]=0.0001;
  27. }
  28.  
  29. //词作为边
  30. struct edgeNode
  31. {
  32. string termText;//词 
  33. int start;//词的开始位置 
  34. int end;//词的结束位置 
  35. float prob;//词在语料库中出现的频率或者概率 
  36. };
  37.  
  38. //分割位置作为点
  39. struct vexNode
  40. {
  41. int nSegNo;  //分割节点编号
  42. list <edgeNode> linkedlist; //与之相连的链表head
  43. };
  44.  
  45. //存储节点信息
  46. vexNode adjlist[NODENUM];
  47.  
  48. //建立邻接表存储
  49.  
  50. void InitialGraph()
  51. {
  52. int i=0;
  53. for(i=0;i<NODENUM;i++)
  54. {
  55. adjlist[i].nSegNo=i;
  56. }
  57. }
  58.  
  59. //插入一条边
  60. void InsertEdge(edgeNode & newEdgeNode)
  61. {
  62. int v1=newEdgeNode.end;
  63. adjlist[v1].linkedlist.push_front(newEdgeNode);
  64. }
  65.  
  66. //形成切分词图
  67. void CreateWordSegGraph(string s)
  68. {
  69. short i=0;
  70. short j=0;
  71. short len=0;
  72. short restlen=0;
  73. short n=s.length();
  74. float freq=0;
  75.  
  76. string w;
  77.  
  78. for(j=0;j<n;j+=2)
  79. {
  80. for(len=2;len<=MaxWordLength;len+=2)
  81. {
  82. restlen=n-j;
  83. if (len<=restlen) // 如果剩余词长度不够长,跳出循环
  84. {
  85. w=s.substr(j,len);
  86. }
  87. else
  88. {
  89. break;
  90. }
  91.  
  92. if (mapWord2Prob.find(w) != mapWord2Prob.end())
  93. {
  94. freq=mapWord2Prob[w];
  95. }
  96. else
  97. {
  98. freq=100;
  99. }
  100.  
  101. if(freq != 100)
  102. {
  103. edgeNode stCandidateWord;
  104. stCandidateWord.termText=w;
  105. stCandidateWord.start=j/MinWordLength;
  106. stCandidateWord.end=(j+len)/MinWordLength;
  107. stCandidateWord.prob = freq;
  108.  
  109. cout<<"插入一条边 word "<<w<<" freq "<<stCandidateWord.prob<<" start "<<stCandidateWord.start<<" end "<<stCandidateWord.end<<endl;
  110.  
  111. InsertEdge(stCandidateWord);
  112. }
  113. }
  114. }
  115. }
  116.  
  117. //寻找i的最佳前趋词
  118. void getPrev(int i)
  119. {
  120. vexNode oVexNode=adjlist[i];
  121. edgeNode oEdgeNode;
  122.  
  123. list <edgeNode>::iterator itList;
  124. //得到前驱词的集合 
  125. float maxProb = 0; 
  126. int maxNode = -1; 
  127.  
  128. //根据前驱词集合挑选最佳前趋节点 
  129. for(itList=oVexNode.linkedlist.begin(); itList!=oVexNode.linkedlist.end();itList++ )
  130. { 
  131. float nodeProb = prob[itList->start]+itList->prob;//候选节点概率 
  132. cout<<"搜索结点 "<<i<<"   其前趋累计概率 "<<nodeProb<<" 开始位置 "<<itList->start<<endl;
  133. if (nodeProb > maxProb)    
  134. { 
  135. //候选节点概率最大的开始节点就是最佳前趋节点 
  136. maxNode = itList->start; 
  137. maxProb = nodeProb; 
  138. } 
  139. } 
  140. prob[i] = maxProb;//节点概率 
  141. prevNode[i] = maxNode;//最佳前驱节点 
  142. cout<<"节点"<<i<<"的最佳前驱节点 "<<maxNode<<" 概率"<< maxProb<<endl;
  143. } 
  144.  
  145. //回溯求最佳分割点
  146. string BestSeg(string strSequence)
  147. {
  148. string strSeg="";
  149. int nLeft=0;
  150. int nRight=0;
  151. for(int i=strSequence.length()/MinWordLength; i>0;i=prevNode[i])
  152. {
  153. cout<<"最佳路径结点 "<<i<<endl;
  154. nRight=i;
  155. nLeft=prevNode[i];
  156. cout<<"词 "<<strSequence.substr(nLeft*MinWordLength,(nRight-nLeft)*MinWordLength)<<endl;
  157. strSeg=strSequence.substr(nLeft*MinWordLength,(nRight-nLeft)*MinWordLength)+strDelimiter+strSeg;
  158. }
  159. return strSeg;
  160. }
  161.  
  162. //int main(int argc, char * argv[])
  163. int _tmain(int argc, _TCHAR* argv[])
  164. {
  165. LoadDict();
  166. InitialGraph();
  167. for (int i=0;i<NODENUM;i++)
  168. {
  169. prob[i]=0;
  170. prevNode[i]=0;
  171. }
  172. string strSequence="有意见分歧";
  173. //构建邻接表表示的切分词图,(有向图)
  174. CreateWordSegGraph(strSequence);
  175.  
  176.  
  177. cout<<"寻找最佳前趋__________________________"<<endl;
  178.  
  179. for (int i=1;i<=strSequence.length()/MinWordLength;i++)
  180. {
  181. getPrev(i);
  182. }
  183. cout<<"最佳切分路径 "<<endl;
  184. cout<<"分词结果 "<<BestSeg(strSequence)<<endl;
  185.  
  186. int m = 0;
  187. cin>>m;
  188. return 0;
  189. }

与相关的文章
有时间的话来看看IT界的突发事件