Utility.cpp
上传用户:yxl0916
上传日期:2007-05-25
资源大小:2245k
文件大小:18k
源码类别:

多国语言处理

开发平台:

Visual C++

  1. //////////////////////////////////////////////////////////////////////
  2. //ICTCLAS简介:计算所汉语词法分析系统ICTCLAS(Institute of Computing Technology, Chinese Lexical Analysis System),
  3. //             功能有:中文分词;词性标注;未登录词识别。
  4. //             分词正确率高达97.58%(973专家评测结果),
  5. //             未登录词识别召回率均高于90%,其中中国人名的识别召回率接近98%;
  6. //             处理速度为31.5Kbytes/s。
  7. //著作权:  Copyright?2002-2005中科院计算所 职务著作权人:张华平 刘群
  8. //遵循协议:自然语言处理开放资源许可证1.0
  9. //Email: zhanghp@software.ict.ac.cn
  10. //Homepage:www.nlp.org.cn;mtgroup.ict.ac.cn
  11. /****************************************************************************
  12.  *
  13.  * Copyright (c) 2000, 2001 
  14.  *     Machine Group
  15.  *     Software Research Lab.
  16.  *     Institute of Computing Tech.
  17.  *     Chinese Academy of Sciences
  18.  *     All rights reserved.
  19.  *
  20.  * This file is the confidential and proprietary property of 
  21.  * Institute of Computing Tech. and the posession or use of this file requires 
  22.  * a written license from the author.
  23.  * Filename: Utility.c
  24.  * Abstract:
  25.  *           Utility functions for Chinese Language Processing
  26.  * Author:   Kevin Zhang 
  27.  *          (zhanghp@software.ict.ac.cn)
  28.  * Date:     2002-1-8
  29.  *
  30.  * Notes:
  31.  *                
  32.  ****************************************************************************/
  33. #include "stdafx.h"
  34. #include "Utility.h"
  35. #include <stdio.h>
  36. #include <string.h>
  37. /*********************************************************************
  38.  *
  39.  *  Func Name  : GB2312_Generate
  40.  *
  41.  *  Description:  Generate the GB2312 List file
  42.  *              
  43.  *
  44.  *  Parameters : sFilename: the file name for the output GB2312 List
  45.  *    
  46.  *  Returns    : bool
  47.  *  Author     : Kevin Zhang  
  48.  *  History    : 
  49.  *              1.create 2002-1-8
  50.  *********************************************************************/
  51. bool GB2312_Generate(char *sFileName)
  52. {
  53.    FILE *fp;
  54.    unsigned int i,j;
  55.    if((fp=fopen(sFileName,"wt"))==NULL)
  56.    return false;//fail while opening the file
  57.    for(i=161;i<255;i++)
  58.    for(j=161;j<255;j++)
  59.    fprintf(fp,"%c%c,%d,%dn",i,j,i,j);
  60.    fclose(fp);
  61.    return true;
  62. }
  63. /*********************************************************************
  64.  *
  65.  *  Func Name  : CC_Generate
  66.  *
  67.  *  Description:  Generate the Chinese Char List file
  68.  *              
  69.  *
  70.  *  Parameters : sFilename: the file name for the output CC List
  71.  *    
  72.  *  Returns    : bool
  73.  *  Author     : Kevin Zhang  
  74.  *  History    : 
  75.  *              1.create 2002-1-8
  76.  *********************************************************************/
  77. bool CC_Generate(char *sFileName)
  78. {
  79.    FILE *fp;
  80.    unsigned int i,j;
  81.    if((fp=fopen(sFileName,"wt"))==NULL)
  82.    return false;//fail while opening the file
  83.    for(i=176;i<255;i++)
  84.    for(j=161;j<255;j++)
  85.    fprintf(fp,"%c%c,%d,%dn",i,j,i,j);
  86.    fclose(fp);
  87.    return true;
  88. }
  89. /*********************************************************************
  90.  *
  91.  *  Func Name  : CC_Find
  92.  *
  93.  *  Description: Find a Chinese sub-string in the Chinese String 
  94.  *              
  95.  *
  96.  *  Parameters :  string:Null-terminated string to search
  97.  *
  98.  *        strCharSet:Null-terminated string to search for
  99.  *
  100.  *  Returns    : char *
  101.  *  Author     : Kevin Zhang  
  102.  *  History    : 
  103.  *              1.create 2002-1-8
  104.  *********************************************************************/
  105. char *CC_Find(const char *string, const char *strCharSet)
  106. {
  107.    char *cp=strstr(string,strCharSet);
  108.    if(cp!=NULL&&(cp-string)%2==1)
  109.    {
  110.   return NULL;
  111.    }
  112.    return cp;
  113. }
  114. /*********************************************************************
  115.  *
  116.  *  Func Name  : charType
  117.  *
  118.  *  Description: Judge the type of sChar or (sChar,sChar+1)
  119.  *              
  120.  *
  121.  *  Parameters : sFilename: the file name for the output CC List
  122.  *    
  123.  *  Returns    : int : the type of char
  124.  *  Author     : Kevin Zhang  
  125.  *  History    : 
  126.  *              1.create 2002-1-8
  127.  *********************************************************************/
  128. int charType(unsigned char *sChar)
  129. {
  130.   if(*sChar<128)
  131.   {
  132.  if(strchr("42!,.?()[]{}+=",(int)*sChar))
  133.  return CT_DELIMITER;
  134.  return CT_SINGLE;
  135.   }
  136.   else if(*sChar==162)
  137.   return CT_INDEX;
  138.   else if(*sChar==163&&*(sChar+1)>175&&*(sChar+1)<186)
  139.   return CT_NUM;
  140.   else if(*sChar==163&&(*(sChar+1)>=193&&*(sChar+1)<=218||*(sChar+1)>=225&&*(sChar+1)<=250))
  141.   return CT_LETTER;
  142.   else if(*sChar==161||*sChar==163)
  143.   return CT_DELIMITER;
  144.   else if(*sChar>=176&&*sChar<=247)
  145.       return CT_CHINESE;
  146.   else
  147.       return CT_OTHER;
  148. }
  149. /*********************************************************************
  150.  *
  151.  *  Func Name  : GetCCPrefix
  152.  *
  153.  *  Description: Get the max Prefix string made up of Chinese Char
  154.  *              
  155.  *
  156.  *  Parameters : sSentence: the original sentence which includes Chinese or Non-Chinese char
  157.  *    
  158.  *  Returns    : the end of the sub-sentence
  159.  *  Author     : Kevin Zhang  
  160.  *  History    : 
  161.  *              1.create 2002-1-8
  162.  *********************************************************************/
  163. unsigned int  GetCCPrefix(unsigned char *sSentence)
  164. {
  165.    unsigned int nLen=strlen((const char *)sSentence),nCurPos=0;
  166.    while(nCurPos<nLen&&sSentence[nCurPos]>175&&sSentence[nCurPos]<248)
  167.    {
  168.       nCurPos+=2;//Get next Chinese Char
  169.    }
  170.    return nCurPos;
  171. }
  172. /*********************************************************************
  173.  *
  174.  *  Func Name  : IsAllSingleByte
  175.  *
  176.  *  Description: Judge the string is all made up of Single Byte Char
  177.  *              
  178.  *
  179.  *  Parameters : sSentence: the original sentence which includes Chinese or Non-Chinese char
  180.  *    
  181.  *  Returns    : the end of the sub-sentence
  182.  *  Author     : Kevin Zhang  
  183.  *  History    : 
  184.  *              1.create 2002-1-24
  185.  *********************************************************************/
  186. bool IsAllChinese(unsigned char *sString)
  187. {
  188. unsigned int nLen=strlen((const char *)sString),i=0;
  189. while(i<nLen-1&&sString[i]<248&&sString[i]>175)
  190. {
  191. i+=2;
  192. }
  193. if(i<nLen)
  194. return false;
  195. return true;
  196. }
  197. /*********************************************************************
  198.  *
  199.  *  Func Name  : IsAllNonChinese
  200.  *
  201.  *  Description: Judge the string is all made up of Single Byte Char
  202.  *              
  203.  *
  204.  *  Parameters : sSentence: the original sentence which includes Chinese or Non-Chinese char
  205.  *    
  206.  *  Returns    : the end of the sub-sentence
  207.  *  Author     : Kevin Zhang  
  208.  *  History    : 
  209.  *              1.create 2002-1-24
  210.  *********************************************************************/
  211. bool IsAllNonChinese(unsigned char *sString)
  212. {
  213. unsigned int nLen=strlen((const char *)sString),i=0;
  214. while(i<nLen)
  215. {
  216. if(sString[i]<248&&sString[i]>175)
  217. return false;
  218. if(sString[i]>128)
  219. i+=2;
  220. else
  221. i+=1;
  222. }
  223.     return true;
  224. }
  225. /*********************************************************************
  226.  *
  227.  *  Func Name  : IsAllSingleByte
  228.  *
  229.  *  Description: Judge the string is all made up of Single Byte Char
  230.  *              
  231.  *
  232.  *  Parameters : sSentence: the original sentence which includes Chinese or Non-Chinese char
  233.  *    
  234.  *  Returns    : the end of the sub-sentence
  235.  *  Author     : Kevin Zhang  
  236.  *  History    : 
  237.  *              1.create 2002-1-24
  238.  *********************************************************************/
  239. bool IsAllSingleByte(unsigned char *sString)
  240. {
  241. unsigned int nLen=strlen((const char *)sString),i=0;
  242. while(i<nLen&&sString[i]<128)
  243. {
  244. i++;
  245. }
  246. if(i<nLen)
  247. return false;
  248. return true;
  249. }
  250. /*********************************************************************
  251.  *
  252.  *  Func Name  : IsAllNum
  253.  *
  254.  *  Description: Judge the string is all made up of Num Char
  255.  *              
  256.  *
  257.  *  Parameters : sSentence: the original sentence which includes Chinese or Non-Chinese char
  258.  *    
  259.  *  Returns    : the end of the sub-sentence
  260.  *  Author     : Kevin Zhang  
  261.  *  History    : 
  262.  *              1.create 2002-1-24
  263.  *********************************************************************/
  264. bool IsAllNum(unsigned char *sString)
  265. {
  266. unsigned int nLen=strlen((const char *)sString),i=0;
  267. char sChar[3];
  268. sChar[2]=0;
  269. if(i<nLen)//Get prefix such as + -
  270. {
  271. sChar[0]=sString[i++];
  272. if(sChar[0]<0)//Get first char
  273. sChar[1]=sString[i++];
  274. else
  275. sChar[1]=0;
  276. if(!strstr("±+—-+",sChar))
  277. {
  278. i=0;
  279. }
  280. }
  281. while(i<nLen-1&&sString[i]==163&&sString[i+1]>175&&sString[i+1]<186)
  282. {
  283. i+=2;
  284. }
  285. if(i<nLen)//Get middle delimiter such as .
  286. {
  287. sChar[0]=sString[i++];
  288. if(sChar[0]<0)//Get first char
  289. sChar[1]=sString[i++];
  290. else
  291. sChar[1]=0;
  292. if(CC_Find("∶·./",sChar)||sChar[0]=='.'||sChar[0]=='/')
  293. {//98.1%
  294. while(i<nLen-1&&sString[i]==163&&sString[i+1]>175&&sString[i+1]<186)
  295. {
  296. i+=2;
  297. }
  298. }
  299. else
  300. {
  301. i-=strlen(sChar);
  302. }
  303. }
  304. if(i>=nLen)
  305. return true;
  306. while(i<nLen&&sString[i]>'0'-1&&sString[i]<'9'+1)
  307. {//single byte number char
  308. i+=1;
  309. }
  310. if(i<nLen)//Get middle delimiter such as .
  311. {
  312. sChar[0]=sString[i++];
  313. if(sChar[0]<0)//Get first char
  314. sChar[1]=sString[i++];
  315. else
  316. sChar[1]=0;
  317. if(CC_Find("∶·./",sChar)||sChar[0]=='.'||sChar[0]=='/')
  318. {//98.1%
  319. while(i<nLen&&sString[i]>'0'-1&&sString[i]<'9'+1)
  320. {
  321. i+=1;
  322. }
  323. }
  324. else
  325. {
  326. i-=strlen(sChar);
  327. }
  328. }
  329. if(i<nLen)//Get middle delimiter such as .
  330. {
  331. sChar[0]=sString[i++];
  332. if(sChar[0]<0)//Get first char
  333. sChar[1]=sString[i++];
  334. else
  335. sChar[1]=0;
  336. if(!CC_Find("百千万亿佰仟%‰",sChar)&&sChar[0]!='%')
  337. i-=strlen(sChar);
  338. }
  339. if(i>=nLen)
  340. return true;
  341. return false;
  342. }
  343. /*********************************************************************
  344.  *
  345.  *  Func Name  : IsAllIndex
  346.  *
  347.  *  Description: Judge the string is all made up of Index Num Char
  348.  *              
  349.  *
  350.  *  Parameters : sSentence: the original sentence which includes Chinese or Non-Chinese char
  351.  *    
  352.  *  Returns    : the end of the sub-sentence
  353.  *  Author     : Kevin Zhang  
  354.  *  History    : 
  355.  *              1.create 2002-1-24
  356.  *********************************************************************/
  357. bool IsAllIndex(unsigned char *sString)
  358. {
  359. unsigned int nLen=strlen((const char *)sString),i=0;
  360. while(i<nLen-1&&sString[i]==162)
  361. {
  362. i+=2;
  363. }
  364. if(i>=nLen)
  365. return true;
  366.  while(i<nLen&&(sString[i]>'A'-1&&sString[i]<'Z'+1)||(sString[i]>'a'-1&&sString[i]<'z'+1))
  367.  {//single byte number char
  368. i+=1;
  369.  }
  370. if(i<nLen)
  371. return false;
  372. return true;
  373. }
  374. /*********************************************************************
  375.  *
  376.  *  Func Name  : IsAllLetter
  377.  *
  378.  *  Description: Judge the string is all made up of Letter Char
  379.  *              
  380.  *
  381.  *  Parameters : sSentence: the original sentence which includes Chinese or Non-Chinese char
  382.  *    
  383.  *  Returns    : the end of the sub-sentence
  384.  *  Author     : Kevin Zhang  
  385.  *  History    : 
  386.  *              1.create 2002-1-24
  387.  *********************************************************************/
  388. bool IsAllLetter(unsigned char *sString)
  389. {
  390. unsigned int nLen=strlen((const char *)sString),i=0;
  391. while(i<nLen-1&&sString[i]==163&&((sString[i+1]>=193&&sString[i+1]<=218)||(sString[i+1]>=225&&sString[i+1]<=250)))
  392. {
  393. i+=2;
  394. }
  395. if(i<nLen)
  396. return false;
  397. return true;
  398. }
  399. /*********************************************************************
  400.  *
  401.  *  Func Name  : IsAllDelimiter
  402.  *
  403.  *  Description: Judge the string is all made up of Delimiter
  404.  *              
  405.  *
  406.  *  Parameters : sSentence: the original sentence which includes Chinese or Non-Chinese char
  407.  *    
  408.  *  Returns    : the end of the sub-sentence
  409.  *  Author     : Kevin Zhang  
  410.  *  History    : 
  411.  *              1.create 2002-1-24
  412.  *********************************************************************/
  413. bool IsAllDelimiter(unsigned char *sString)
  414. {
  415. unsigned int nLen=strlen((const char *)sString),i=0;
  416. while(i<nLen-1&&(sString[i]==161||sString[i]==163))
  417. {
  418. i+=2;
  419. }
  420. if(i<nLen)
  421. return false;
  422. return true;
  423. }
  424. /*********************************************************************
  425.  *
  426.  *  Func Name  : BinarySearch
  427.  *
  428.  *  Description: Lookup the index of nVal in the table nTable which length is nTableLen
  429.  *
  430.  *  Parameters : nPOS: the POS value
  431.  *
  432.  *  Returns    : the index value
  433.  *  Author     : Kevin Zhang  
  434.  *  History    : 
  435.  *              1.create 2002-1-25
  436.  *********************************************************************/
  437. int BinarySearch(int nVal, int *nTable,int nTableLen)
  438. {
  439. int nStart=0,nEnd=nTableLen-1,nMid=(nStart+nEnd)/2;
  440. while(nStart<=nEnd)//Binary search
  441. {
  442.        if(nTable[nMid]==nVal)
  443.    {
  444. return nMid;//find it
  445.    }
  446.    else if(nTable[nMid]<nVal)
  447.    {
  448.    nStart=nMid+1;
  449.    }
  450.    else
  451.        {
  452.    nEnd=nMid-1;
  453.    }
  454.    nMid=(nStart+nEnd)/2;
  455. }
  456. return -1;//Can not find it;
  457. }
  458. /*********************************************************************
  459.  *
  460.  *  Func Name  : IsForeign
  461.  *
  462.  *  Description: Decide whether the word is not a Non-fereign word
  463.  *
  464.  *  Parameters : sWord: the word
  465.  *
  466.  *  Returns    : the index value
  467.  *  Author     : Kevin Zhang  
  468.  *  History    : 
  469.  *              1.create 2002-1-26
  470.  *********************************************************************/
  471. bool IsForeign(char *sWord)
  472. {
  473.   int nForeignCount=GetForeignCharCount(sWord),nCharCount=strlen(sWord);
  474.   if(nCharCount>2||nForeignCount>=1*nCharCount/2)
  475.   return true;
  476.   return false;
  477. }
  478. /*********************************************************************
  479.  *
  480.  *  Func Name  : IsAllForeign
  481.  *
  482.  *  Description: Decide whether the word is not a Non-fereign word
  483.  *
  484.  *  Parameters : sWord: the word
  485.  *
  486.  *  Returns    : the index value
  487.  *  Author     : Kevin Zhang  
  488.  *  History    : 
  489.  *              1.create 2002-3-25
  490.  *********************************************************************/
  491. bool IsAllForeign(char *sWord)
  492. {
  493.   unsigned int nForeignCount=(unsigned int)GetForeignCharCount(sWord);
  494.   if(2*nForeignCount==strlen(sWord))
  495.   return true;
  496.   return false;
  497. }
  498. /*********************************************************************
  499.  *
  500.  *  Func Name  : IsForeign
  501.  *
  502.  *  Description: Decide whether the word is Chinese Num word
  503.  *
  504.  *  Parameters : sWord: the word
  505.  *
  506.  *  Returns    : the index value
  507.  *  Author     : Kevin Zhang  
  508.  *  History    : 
  509.  *              1.create 2002-1-26
  510.  *********************************************************************/
  511. bool IsAllChineseNum(char *sWord)
  512. {//百分之五点六的人早上八点十八分起床
  513.   unsigned int  k; 
  514.   char tchar[3];
  515.   char ChineseNum[]="零○一二两三四五六七八九十廿百千万亿壹贰叁肆伍陆柒捌玖拾佰仟∶·./点";//
  516.   char sPrefix[]="几数第上成";
  517.   for(k = 0; k < strlen(sWord); k+=2)
  518.   {
  519.      strncpy(tchar,sWord+k,2) ;
  520.      tchar[2]='';
  521.  if(strncmp(sWord+k,"分之",4)==0)//百分之五
  522.  {
  523. k+=2;
  524. continue;
  525.  }
  526.  if(!CC_Find(ChineseNum, tchar)&&!(k==0&&CC_Find(sPrefix, tchar)))
  527.  return false;
  528.   }
  529.   return true;
  530. }
  531. /*********************************************************************
  532.  *
  533.  *  Func Name  : GetForeignCharCount
  534.  *
  535.  *  Description: 
  536.  *
  537.  *  Parameters : sWord: the word
  538.  *
  539.  *  Returns    : the index value
  540.  *  Author     : Kevin Zhang  
  541.  *  History    : 
  542.  *              1.create 2002-4-4
  543.  *              2.Modify  2002-5-21
  544.  *********************************************************************/
  545. int GetForeignCharCount(char *sWord)
  546. {
  547.   unsigned int nForeignCount,nCount;
  548.   nForeignCount=GetCharCount(TRANS_ENGLISH,sWord);//English char counnts
  549.   nCount=GetCharCount(TRANS_JAPANESE,sWord);//Japan char counnts
  550.   if(nForeignCount<=nCount)
  551. nForeignCount=nCount;
  552.   nCount=GetCharCount(TRANS_RUSSIAN,sWord);//Russian char counnts
  553.   if(nForeignCount<=nCount)
  554. nForeignCount=nCount;
  555.   return nForeignCount;
  556. }
  557. /*********************************************************************
  558.  *
  559.  *  Func Name  : GetCharCount
  560.  *
  561.  *  Description: Get the count of char which is in sWord and in sCharSet
  562.  *
  563.  *  Parameters : sWord: the word
  564.  * 
  565.  *  Returns    : COUNT
  566.  *  Author     : Kevin Zhang  
  567.  *  History    : 
  568.  *              1.create 2002-5-21
  569.  *********************************************************************/
  570. int GetCharCount(char *sCharSet,char *sWord)
  571. {
  572.   unsigned int  k=0; 
  573.   char tchar[3];
  574.   int nCount=0;
  575.   tchar[2]=0;
  576.   while(k < strlen(sWord))
  577.   {
  578.      tchar[0]=sWord[k];
  579.    tchar[1]=0;
  580.  if(sWord[k]<0)
  581.  {
  582.  tchar[1]=sWord[k+1];
  583.  k+=1;
  584.  }
  585.  k+=1;
  586.  if((tchar[0]<0&&CC_Find(sCharSet, tchar))||strchr(sCharSet,tchar[0]))
  587.           nCount++;
  588.   }
  589.   return nCount;
  590. }
  591. /*********************************************************************
  592.  *
  593.  *  Func Name  : GetForeignCharCount
  594.  *
  595.  *  Description: Return the foreign type 
  596.  *
  597.  *  Parameters : sWord: the word
  598.  *
  599.  *  Returns    : the index value
  600.  *  Author     : Kevin Zhang  
  601.  *  History    : 
  602.  *              1.create 2002-4-4
  603.  *              2.Modify  2002-5-21
  604.  *********************************************************************/
  605. int GetForeignType(char *sWord)
  606. {
  607.   unsigned int nForeignCount,nCount,nType=TT_ENGLISH;
  608.   nForeignCount=GetCharCount(TRANS_ENGLISH,sWord);//English char counnts
  609.   nCount=GetCharCount(TRANS_RUSSIAN,sWord);//Russian char counnts
  610.   if(nForeignCount<nCount)
  611.   {
  612.   nForeignCount=nCount;
  613.   nType=TT_RUSSIAN;
  614.   }
  615.   nCount=GetCharCount(TRANS_JAPANESE,sWord);//Japan char counnts
  616.   if(nForeignCount<nCount)
  617.   {
  618.   nForeignCount=nCount;
  619.   nType=TT_JAPANESE;
  620.   }
  621.   return nType;
  622. }
  623. bool PostfixSplit(char *sWord, char *sWordRet, char *sPostfix)
  624. {
  625. char sSinglePostfix[]=POSTFIX_SINGLE;
  626. char sMultiPostfix[][9]=POSTFIX_MUTIPLE;
  627. unsigned int nPostfixLen=0,nWordLen=strlen(sWord);
  628. int i=0;
  629. while(sMultiPostfix[i][0]!=0&&strncmp(sWord+nWordLen-strlen(sMultiPostfix[i]),sMultiPostfix[i],strlen(sMultiPostfix[i]))!=0)
  630. {//Try to get the postfix of an address
  631. i++;
  632. }
  633. strcpy(sPostfix,sMultiPostfix[i]);
  634. nPostfixLen=strlen(sMultiPostfix[i]);//Get the length of place postfix
  635. if(nPostfixLen==0)
  636. {
  637. sPostfix[2]=0;
  638. strncpy(sPostfix,sWord+nWordLen-2,2);
  639. if(CC_Find(sSinglePostfix,sPostfix))
  640. nPostfixLen=2;
  641. }
  642. strncpy(sWordRet,sWord,nWordLen-nPostfixLen);
  643. sWordRet[nWordLen-nPostfixLen]=0;//Get the place name which have erasing the postfix
  644. sPostfix[nPostfixLen]=0;
  645.     return true;
  646. }