Utility.cpp
上传用户:jxhy0791
上传日期:2007-05-24
资源大小:6173k
文件大小:17k
源码类别:

多国语言处理

开发平台:

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