Segment.cpp
上传用户:chen_dj
上传日期:2013-04-22
资源大小:111k
文件大小:9k
源码类别:

多国语言处理

开发平台:

C/C++

  1. /****************************************************************************
  2.  *
  3.  * Copyright (c) 2000, 2001 
  4.  *     Machine Group
  5.  *     Software Research Lab.
  6.  *     Institute of Computing Tech.
  7.  *     Chinese Academy of Sciences
  8.  *     All rights reserved.
  9.  *
  10.  * This file is the confidential and proprietary property of 
  11.  * Institute of Computing Tech. and the posession or use of this file requires 
  12.  * a written license from the author.
  13.  * Filename: Segment.cpp
  14.  * Abstract:
  15.  *           implementation of the CSegment class.
  16.  * Author:   Kevin Zhang 
  17.  *          (zhanghp@software.ict.ac.cn)
  18.  * Date:     2002-4-23
  19.  *
  20.  * Notes:  N-Shortest paths Word segmentation
  21.  *                
  22.  ****************************************************************************/
  23. #include "stdafx.h"
  24. #include "Segment.h"
  25. #include "..\Utility\Dictionary.h"
  26. #include "..\Utility\Utility.h"
  27. #include "NShortPath.h"
  28. #include <string.h>
  29. #include <math.h>
  30. //////////////////////////////////////////////////////////////////////
  31. // Construction/Destruction
  32. //////////////////////////////////////////////////////////////////////
  33. CSegment::CSegment()
  34. {
  35. //malloc buffer
  36. m_pWordSeg=new PWORD_RESULT[MAX_SEGMENT_NUM];
  37. for(int i=0;i<MAX_SEGMENT_NUM;i++)
  38. {
  39. m_pWordSeg[i]=new WORD_RESULT[MAX_WORDS];
  40. }
  41. }
  42. CSegment::~CSegment()
  43. {
  44. //free buffer
  45. for(int i=0;i<MAX_SEGMENT_NUM;i++)
  46. {
  47. delete m_pWordSeg[i];
  48. }
  49. delete m_pWordSeg;
  50. }
  51. bool CSegment::Segment(char *sSentence,CDictionary &dictCore,int nResultCount)
  52. {
  53. int **nSegRoute;//The segmentation route
  54. nSegRoute=new int*[MAX_SEGMENT_NUM];
  55. for(int i=0;i<MAX_SEGMENT_NUM;i++)
  56. {
  57. nSegRoute[i]=new int[MAX_SENTENCE_LEN/2];
  58. memset(nSegRoute[i],0,MAX_SENTENCE_LEN/2*sizeof(int));
  59. }
  60.   m_graphSeg.GenerateWordNet(sSentence,dictCore);
  61. CNShortPath sp(&m_graphSeg.m_segGraph,nResultCount);
  62. sp.ShortPath();
  63. sp.Output((int **)nSegRoute,false,&m_nSegmentCount);
  64. m_graphOptimum.SetEmpty();//Set graph optimum empty
  65. i=0;
  66. while(i<m_nSegmentCount)
  67. {
  68. GenerateWord(nSegRoute,i);
  69. //Gernerate word according the Segmentation route
  70. i++;
  71. }
  72. //free the memory
  73. for(i=0;i<MAX_SEGMENT_NUM;i++)
  74. {
  75. delete [] nSegRoute[i];//free the pointer memory
  76. }
  77. delete [] nSegRoute;//free the pointer array
  78. return true;
  79. }
  80. //Generate Word according the segmentation route
  81. bool CSegment::GenerateWord(int **nSegRoute, int nIndex)
  82. {
  83. unsigned int i=0,k=0;
  84. int j,nStartVertex,nEndVertex,nPOS;
  85. char sAtom[WORD_MAXLENGTH],sNumCandidate[100];
  86. ELEMENT_TYPE fValue;
  87. while(nSegRoute[nIndex][i]!=-1&&nSegRoute[nIndex][i+1]!=-1&&nSegRoute[nIndex][i]<nSegRoute[nIndex][i+1])
  88. {
  89. nStartVertex=nSegRoute[nIndex][i];
  90. j=nStartVertex;//Set the start vertex
  91. nEndVertex=nSegRoute[nIndex][i+1];//Set the end vertex
  92. nPOS=0;
  93. m_graphSeg.m_segGraph.GetElement(nStartVertex,nEndVertex,&fValue,&nPOS);
  94. sAtom[0]=0;
  95. while(j<nEndVertex)
  96. {//Generate the word according the segmentation route
  97. strcat(sAtom,m_graphSeg.m_sAtom[j]);
  98. j++;
  99. }
  100. m_pWordSeg[nIndex][k].sWord[0]=0;//Init the result ending
  101. strcpy(sNumCandidate,sAtom);
  102. while(sAtom[0]!=0&&(IsAllNum((unsigned char *)sNumCandidate)||IsAllChineseNum(sNumCandidate)))
  103. {//Merge all seperate continue num into one number
  104.  //sAtom[0]!=0: add in 2002-5-9
  105. strcpy(m_pWordSeg[nIndex][k].sWord,sNumCandidate);
  106. //Save them in the result segmentation
  107. i++;//Skip to next atom now 
  108. sAtom[0]=0;
  109. while(j<nSegRoute[nIndex][i+1])
  110. {//Generate the word according the segmentation route
  111. strcat(sAtom,m_graphSeg.m_sAtom[j]);
  112. j++;
  113. }
  114. strcat(sNumCandidate,sAtom);
  115. }
  116. if(m_pWordSeg[nIndex][k].sWord[0]==0)//Have never entering the while loop
  117. {
  118. strcpy(m_pWordSeg[nIndex][k].sWord,sAtom);
  119. //Save them in the result segmentation
  120. }
  121. else
  122. {//It is a num
  123. if(strcmp("--",m_pWordSeg[nIndex][k].sWord)==0||strcmp("—",m_pWordSeg[nIndex][k].sWord)==0||m_pWordSeg[nIndex][k].sWord[0]=='-')//The delimiter "--"
  124. {
  125. nPOS=30464;//'w'*256;Set the POS with 'w'
  126. i--;//Not num, back to previous word
  127. }
  128. else
  129. {//Adding time suffix
  130. char sInitChar[3];
  131. unsigned int nCharIndex=0;//Get first char
  132. sInitChar[nCharIndex]=m_pWordSeg[nIndex][k].sWord[nCharIndex];
  133. if(sInitChar[nCharIndex]<0)
  134. {
  135. nCharIndex+=1;
  136. sInitChar[nCharIndex]=m_pWordSeg[nIndex][k].sWord[nCharIndex];
  137. }
  138. nCharIndex+=1;
  139. sInitChar[nCharIndex]='';
  140. if(k>0&&m_pWordSeg[nIndex][k-1].nHandle==27904&&(strcmp(sInitChar,"—")==0||sInitChar[0]=='-')&&(strlen(m_pWordSeg[nIndex][k].sWord)>nCharIndex))
  141. {//3-4月                                 //27904='m'*256
  142.    //Split the sInitChar from the original word
  143. strcpy(m_pWordSeg[nIndex][k+1].sWord,m_pWordSeg[nIndex][k].sWord+nCharIndex);
  144. m_pWordSeg[nIndex][k+1].dValue=m_pWordSeg[nIndex][k].dValue;
  145. m_pWordSeg[nIndex][k+1].nHandle=27904;
  146. m_pWordSeg[nIndex][k].sWord[nCharIndex]=0;
  147. m_pWordSeg[nIndex][k].dValue=0;
  148. m_pWordSeg[nIndex][k].nHandle=30464;//'w'*256;
  149. m_graphOptimum.SetElement(nStartVertex,nStartVertex+1,m_pWordSeg[nIndex][k].dValue,m_pWordSeg[nIndex][k].nHandle);
  150. nStartVertex+=1;
  151. k+=1;
  152. }
  153. unsigned int nLen=strlen(m_pWordSeg[nIndex][k].sWord);
  154. if((strlen(sAtom)==2&&CC_Find("月日时分秒",sAtom))||strcmp(sAtom,"月份")==0)
  155. {//2001年
  156. strcat(m_pWordSeg[nIndex][k].sWord,sAtom);
  157. nPOS=29696;//'t'*256;//Set the POS with 'm'
  158. }
  159. else if(strcmp(sAtom,"年")==0)
  160. {
  161.  if(IsYearTime(m_pWordSeg[nIndex][k].sWord))//strncmp(sAtom,"年",2)==0&&
  162.  {//1998年,
  163. strcat(m_pWordSeg[nIndex][k++].sWord,sAtom);
  164. nPOS='t'*256;//Set the POS with 'm'
  165.  }
  166.  else
  167.     i--;//Can not be a time word
  168. }
  169.       else
  170. {
  171. //早晨/t  五点/t 
  172. if(strcmp(m_pWordSeg[nIndex][k].sWord+strlen(m_pWordSeg[nIndex][k].sWord)-2,"点")==0)
  173. {
  174. nPOS='t'*256;//Set the POS with 'm'
  175. }
  176. else 
  177. {
  178. if(m_pWordSeg[nIndex][k].sWord[0]!='.')
  179. nPOS='m'*256;//Set the POS with 'm'
  180. if(nLen>1&&m_pWordSeg[nIndex][k].sWord[nLen-1]=='.')
  181. {//Get rid of . example 1.
  182. m_pWordSeg[nIndex][k].sWord[nLen-1]=0;
  183. i--;
  184. }
  185. }
  186. i--;//Not num, back to previous word
  187. }
  188. }
  189. fValue=0;
  190. nEndVertex=nSegRoute[nIndex][i+1];//Ending POS changed to latter
  191. }
  192. m_pWordSeg[nIndex][k].nHandle=nPOS;//Get the POS of current word
  193. m_pWordSeg[nIndex][k].dValue=fValue;//(int)(MAX_FREQUENCE*exp(-fValue));//Return the frequency of current word
  194. m_graphOptimum.SetElement(nStartVertex,nEndVertex,fValue,nPOS);
  195. //Generate optimum segmentation graph according the segmentation result
  196. i++;//Skip to next atom
  197. k++;//Accept next word
  198. }
  199. m_pWordSeg[nIndex][k].sWord[0]=0;
  200. m_pWordSeg[nIndex][k].nHandle=-1;//Set ending
  201. return true;
  202. }
  203. //DEL bool CSegment::GetSegmentResult(int nIndex,char *sResult)
  204. //DEL {
  205. //DEL  int i=0;
  206. //DEL  char sTempBuffer[WORD_MAXLENGTH];
  207. //DEL  sResult[0]=0;
  208. //DEL  if(nIndex<0||nIndex>=m_nSegmentCount)
  209. //DEL  return false;
  210. //DEL  while(m_WordSeg[nIndex][i].sWord[0]!=0)
  211. //DEL  {
  212. //DEL  sprintf(sTempBuffer,"%s/%c%c",m_WordSeg[nIndex][i].sWord,m_WordSeg[nIndex][i].nHandle/256,m_WordSeg[nIndex][i].nHandle%256);
  213. //DEL  strcat(sResult,sTempBuffer);
  214. //DEL  strcat(sResult,"  ");
  215. //DEL  i++;
  216. //DEL  }
  217. //DEL  return true;
  218. //DEL }
  219. //Word Segmentation based on optimum segmentation graph
  220. //After unknown word recognition
  221. bool CSegment::OptimumSegmet(int nResultCount)
  222. {
  223. int **nSegRoute;//The segmentation route
  224. nSegRoute=new int*[MAX_SEGMENT_NUM];
  225. for(int i=0;i<MAX_SEGMENT_NUM;i++)
  226. {
  227. nSegRoute[i]=new int[MAX_SENTENCE_LEN/2];
  228. }
  229. CNShortPath sp(&m_graphOptimum,nResultCount);
  230. sp.ShortPath();
  231. sp.Output((int **)nSegRoute,false,&m_nSegmentCount);
  232. i=0;
  233. m_graphSeg.m_segGraph=m_graphOptimum;
  234. m_graphOptimum.SetEmpty();//Set graph optimum empty
  235. while(i<m_nSegmentCount)
  236. {
  237. GenerateWord(nSegRoute,i);
  238. //Gernerate word according the Segmentation route
  239. i++;
  240. }
  241. //free the memory
  242. for(i=0;i<MAX_SEGMENT_NUM;i++)
  243. {
  244. delete [] nSegRoute[i];//free the pointer memory
  245. }
  246. delete [] nSegRoute;//free the pointer array
  247. return true;
  248. }
  249. int CSegment::GetResultCount(PWORD_RESULT pItem)
  250. {
  251. int nCount=0;
  252. while(pItem[nCount].sWord[0]!=0)
  253. {
  254. nCount+=1;
  255. }
  256. return nCount;
  257. }
  258. bool CSegment::GetLastWord(PWORD_RESULT pItem, char *sWordRet)
  259. {
  260. int nCount=0;
  261. sWordRet[0]=0;
  262. while(pItem[nCount].sWord[0]!=0)
  263. {
  264. strcpy(sWordRet,pItem[nCount].sWord);
  265. nCount+=1;
  266. }
  267. return !sWordRet[0];
  268. }
  269. bool CSegment::IsYearTime(char *sNum)
  270. {//Judge whether the sNum is a num genearating year
  271. unsigned int nLen=strlen(sNum);
  272. char sTemp[3];
  273. strncpy(sTemp,sNum,2);
  274. sTemp[2]=0;
  275. if(IsAllSingleByte((unsigned char *)sNum)&&(nLen>=3||nLen==2&&sNum[0]>'4'))//1992年, 90年
  276. return true;
  277. if(IsAllNum((unsigned char *)sNum)&&(nLen>=6||nLen==4&&CC_Find("56789",sTemp)))
  278. return true;
  279. if(GetCharCount("零○一二三四五六七八九壹贰叁肆伍陆柒捌玖",sNum)==(int)nLen/2&&nLen>=3)
  280. return true;
  281. if(nLen==8&&GetCharCount("千仟零○",sNum)==2)//二仟零二年
  282. return true;
  283. return false;
  284. }