Utility.cpp
上传用户:sunyong76
上传日期:2021-10-03
资源大小:2236k
文件大小:25k
源码类别:

多国语言处理

开发平台:

Java

  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. /*----Added By huangjin@ict.ac.cn 2006-9-13----*/
  108. if(!string||!strCharSet)
  109. return NULL;
  110. /*---------------------------------------------*/
  111.    char *cp=strstr(string,strCharSet);
  112.    if(cp!=NULL&&(cp-string)%2==1)
  113.    {
  114.   return NULL;
  115.    }
  116.    return cp;
  117. }
  118. /*********************************************************************
  119.  *
  120.  *  Func Name  : charType
  121.  *
  122.  *  Description: Judge the type of sChar or (sChar,sChar+1)
  123.  *              
  124.  *
  125.  *  Parameters : sFilename: the file name for the output CC List
  126.  *    
  127.  *  Returns    : int : the type of char
  128.  *  Author     : Kevin Zhang  
  129.  *  History    : 
  130.  *              1.create 2002-1-8
  131.  *********************************************************************/
  132. int charType(unsigned char *sChar)
  133. {
  134.   if(*sChar<128)
  135.   {
  136.   /* 
  137.   * ----- commented by huangjin@ict.ac.cn 2006-5-31 ------ 
  138.   * 
  139.   *  if(strchr("42!,.?()[]{}+=",(int)*sChar))
  140.   *  return CT_DELIMITER;
  141.   *
  142.   */
  143.   /*----Added By huangjin@ict.ac.cn 2006-7-4-----*/
  144.   if(strchr(".,;:?!%(){+}[]/=42'<>",(int)*sChar))  
  145.   return CT_SINGLE_DELIMITER;
  146.   else if(sChar[0]>='0'&&sChar[0]<='9')
  147.    return CT_SINGLE_NUM;
  148.  /*---------------------------------------------*/   
  149.  return CT_SINGLE;
  150.   }
  151.   /*----Added By huangjin@ict.ac.cn 2006-9-13----
  152.   else if(*(sChar+1)<128)//Invalid word
  153.   return CT_OTHER;
  154.   /*---------------------------------------------*/
  155.   else if(*sChar==162)
  156.   return CT_INDEX;
  157.   else if(*sChar==163&&*(sChar+1)>175&&*(sChar+1)<186)
  158.   return CT_NUM;
  159.   else if(*sChar==163&&(*(sChar+1)>=193&&*(sChar+1)<=218||*(sChar+1)>=225&&*(sChar+1)<=250))
  160.   return CT_LETTER;
  161.   else if(*sChar==161||*sChar==163)
  162.   return CT_DELIMITER;
  163.   else if(*sChar>=176&&*sChar<=247)   
  164.   return CT_CHINESE;
  165.   else
  166.       return CT_OTHER;
  167. }
  168. /*********************************************************************
  169.  *
  170.  *  Func Name  : GetCCPrefix
  171.  *
  172.  *  Description: Get the max Prefix string made up of Chinese Char
  173.  *              
  174.  *
  175.  *  Parameters : sSentence: the original sentence which includes Chinese or Non-Chinese char
  176.  *    
  177.  *  Returns    : the end of the sub-sentence
  178.  *  Author     : Kevin Zhang  
  179.  *  History    : 
  180.  *              1.create 2002-1-8
  181.  *********************************************************************/
  182. unsigned int  GetCCPrefix(unsigned char *sSentence)
  183. {
  184.    unsigned int nLen=strlen((const char *)sSentence),nCurPos=0;
  185.    while(nCurPos<nLen&&sSentence[nCurPos]>175&&sSentence[nCurPos]<248)
  186.    {
  187.       nCurPos+=2;//Get next Chinese Char
  188.    }
  189.    return nCurPos;
  190. }
  191. /*********************************************************************
  192.  *
  193.  *  Func Name  : IsAllSingleByte
  194.  *
  195.  *  Description: Judge the string is all made up of Single Byte Char
  196.  *              
  197.  *
  198.  *  Parameters : sSentence: the original sentence which includes Chinese or Non-Chinese char
  199.  *    
  200.  *  Returns    : the end of the sub-sentence
  201.  *  Author     : Kevin Zhang  
  202.  *  History    : 
  203.  *              1.create 2002-1-24
  204.  *********************************************************************/
  205. bool IsAllChinese(unsigned char *sString)
  206. {
  207. unsigned int nLen=strlen((const char *)sString),i=0;
  208. while(i<nLen-1&&sString[i]<248&&sString[i]>175)
  209. {
  210. i+=2;
  211. }
  212. if(i<nLen)
  213. return false;
  214. return true;
  215. }
  216. /*********************************************************************
  217.  *
  218.  *  Func Name  : IsAllNonChinese
  219.  *
  220.  *  Description: Judge the string is all made up of Single Byte Char
  221.  *              
  222.  *
  223.  *  Parameters : sSentence: the original sentence which includes Chinese or Non-Chinese char
  224.  *    
  225.  *  Returns    : the end of the sub-sentence
  226.  *  Author     : Kevin Zhang  
  227.  *  History    : 
  228.  *              1.create 2002-1-24
  229.  *********************************************************************/
  230. bool IsAllNonChinese(unsigned char *sString)
  231. {
  232. unsigned int nLen=strlen((const char *)sString),i=0;
  233. while(i<nLen)
  234. {
  235. if(sString[i]<248&&sString[i]>175)
  236. return false;
  237. if(sString[i]>128)
  238. i+=2;
  239. else
  240. i+=1;
  241. }
  242.     return true;
  243. }
  244. /*********************************************************************
  245.  *
  246.  *  Func Name  : IsAllSingleByte
  247.  *
  248.  *  Description: Judge the string is all made up of Single Byte Char
  249.  *              
  250.  *
  251.  *  Parameters : sSentence: the original sentence which includes Chinese or Non-Chinese char
  252.  *    
  253.  *  Returns    : the end of the sub-sentence
  254.  *  Author     : Kevin Zhang  
  255.  *  History    : 
  256.  *              1.create 2002-1-24
  257.  *********************************************************************/
  258. bool IsAllSingleByte(unsigned char *sString)
  259. {
  260. unsigned int nLen=strlen((const char *)sString),i=0;
  261. while(i<nLen&&sString[i]<128)
  262. {
  263. i++;
  264. }
  265. if(i<nLen)
  266. return false;
  267. return true;
  268. }
  269. /*********************************************************************
  270.  *
  271.  *  Func Name  : IsAllNum
  272.  *
  273.  *  Description: Judge the string is all made up of Num Char
  274.  *              
  275.  *
  276.  *  Parameters : sSentence: the original sentence which includes Chinese or Non-Chinese char
  277.  *    
  278.  *  Returns    : the end of the sub-sentence
  279.  *  Author     : Kevin Zhang  
  280.  *  History    : 
  281.  *              1.create 2002-1-24
  282.  *********************************************************************/
  283. /* 
  284. * ----- commented by huangjin@ict.ac.cn 2006-6-2 ------ 
  285. *
  286. bool IsAllNum(unsigned char *sString)
  287. {
  288. unsigned int nLen=strlen((const char *)sString),i=0;
  289. char sChar[3];
  290. sChar[2]=0;
  291. if(i<nLen)//Get prefix such as + -
  292. {
  293. sChar[0]=sString[i++];
  294. if(sChar[0]<0)//Get first char
  295. sChar[1]=sString[i++];
  296. else
  297. sChar[1]=0;
  298. if(!strstr("±+—-+",sChar))
  299. {
  300. i=0;
  301. }
  302. }
  303. while(i<nLen-1&&sString[i]==163&&sString[i+1]>175&&sString[i+1]<186)
  304. {
  305. i+=2;
  306. }
  307. if(i<nLen)//Get middle delimiter such as .
  308. {
  309. sChar[0]=sString[i++];
  310. if(sChar[0]<0)//Get first char
  311. sChar[1]=sString[i++];
  312. else
  313. sChar[1]=0;
  314. if(CC_Find("∶·./",sChar)||sChar[0]=='.'||sChar[0]=='/')
  315. {//98.1%
  316. while(i<nLen-1&&sString[i]==163&&sString[i+1]>175&&sString[i+1]<186)
  317. {
  318. i+=2;
  319. }
  320. }
  321. else
  322. {
  323. i-=strlen(sChar);
  324. }
  325. }
  326. if(i>=nLen)
  327. return true;
  328. while(i<nLen&&sString[i]>'0'-1&&sString[i]<'9'+1)
  329. {//single byte number char
  330. i+=1;
  331. }
  332. if(i<nLen)//Get middle delimiter such as .
  333. {
  334. sChar[0]=sString[i++];
  335. if(sChar[0]<0)//Get first char
  336. sChar[1]=sString[i++];
  337. else
  338. sChar[1]=0;
  339. if(CC_Find("∶·./",sChar)||sChar[0]=='.'||sChar[0]=='/')
  340. {//98.1%
  341. while(i<nLen&&sString[i]>'0'-1&&sString[i]<'9'+1)
  342. {
  343. i+=1;
  344. }
  345. }
  346. else
  347. {
  348. i-=strlen(sChar);
  349. }
  350. }
  351. if(i<nLen)//Get middle delimiter such as .
  352. {
  353. sChar[0]=sString[i++];
  354. if(sChar[0]<0)//Get first char
  355. sChar[1]=sString[i++];
  356. else
  357. sChar[1]=0;
  358. if(!CC_Find("百千万亿佰仟%‰",sChar)&&sChar[0]!='%')
  359. i-=strlen(sChar);
  360. }
  361. if(i>=nLen)
  362. return true;
  363. return false;
  364. }
  365. *
  366. */
  367. /*----Added By huangjin@ict.ac.cn 2006-6-2----*/
  368. bool IsAllNum(unsigned char *sString)
  369. {
  370. unsigned int nLen=strlen((const char *)sString),i=0;
  371. char sChar[3];
  372. sChar[2]=0;
  373. if(i<nLen)//Get prefix such as + -
  374. {
  375. sChar[0]=sString[i++];
  376. if(sChar[0]<0)//Get first char
  377. sChar[1]=sString[i++];
  378. else
  379. sChar[1]=0;
  380. /* 
  381. * ----- commented by huangjin@ict.ac.cn 2006-7-18 ------ 
  382. *
  383. *  if(!CC_Find("±第—+",sChar)&&!strchr("+-.",sChar[0]))//在句子中是否可以找到子串
  384. *
  385. */
  386. /*----Added By huangjin@ict.ac.cn 2006-7-18----*/
  387. if(!CC_Find("±第-+",sChar)&&!strchr("+-.",sChar[0]))//在句子中是否可以找到子串
  388. /*---------------------------------------------*/
  389. {
  390. i=0;
  391. }
  392. else if ( strlen(sChar)==nLen && sChar[0]=='.')
  393. {//只有一个简单的起始符号是不行的
  394. return false;
  395. }
  396. }
  397. bool bMatch=true;
  398. bool bDBC = true;//用来控制要么全是半角要么全是全角
  399. bool bSBC = true;
  400. while( i<nLen && bMatch )
  401. {
  402. bMatch=false;
  403. if(bDBC&&i<nLen-1&&sString[i]==163&&sString[i+1]>175&&sString[i+1]<186 )
  404. {//判断汉字是否为"0 1 2 3 4 5 6 7 8 9",需用两个字节判断
  405. bSBC=false;
  406. bMatch=true;
  407. do
  408. {
  409. i+=2;
  410. }while(bDBC&&i<nLen-1&&sString[i]==163&&sString[i+1]>175&&sString[i+1]<186);
  411. }
  412. else if(bSBC&&i<nLen&&sString[i]>'0'-1&&sString[i]<'9'+1)
  413. {//single byte number char
  414. bDBC=false;
  415. bMatch=true;
  416. do
  417. {
  418. i+=1;
  419. }while(bSBC&&i<nLen&&sString[i]>'0'-1&&sString[i]<'9'+1);
  420. }
  421. if(i<nLen&&bMatch)//Get middle delimiter such as .
  422. {
  423. sChar[0]=sString[i++];
  424. if(sChar[0]<0)//Get first char
  425. sChar[1]=sString[i++];
  426. else
  427. sChar[1]=0;
  428. if(!CC_Find("∶·./",sChar)&&!strchr(":./",sChar[0]))
  429. {//98.1%
  430. i-=strlen(sChar);
  431. break;
  432. }
  433. }
  434. if(i>=nLen&&bMatch)
  435. return true;
  436. }
  437. if(i<nLen)//postfix
  438. {
  439. /* 
  440. * ----- commented by huangjin@ict.ac.cn 2006-7-18 ------ 
  441. *
  442. *  sChar[0]=sString[i++];
  443. * if(sChar[0]<0)//Get first char
  444. * sChar[1]=sString[i++];
  445. * else
  446. * sChar[1]=0;
  447. * if(!CC_Find("百千万亿佰仟%‰",sChar)&&sChar[0]!='%')
  448. * i-=strlen(sChar);
  449. *
  450. */
  451. /*----Added By huangjin@ict.ac.cn 2006-7-18----*/
  452. //可能是多个后缀,比如42万亿
  453. do
  454. {
  455. sChar[0]=sString[i++];
  456. if(sChar[0]<0)
  457. sChar[1]=sString[i++];
  458. else
  459. sChar[1]=0;
  460. if(CC_Find("%‰",sChar)||sChar[0]=='%')
  461. {
  462. break;
  463. }
  464. else if(CC_Find("百千万亿佰仟兆",sChar))
  465. {
  466. continue;
  467. }
  468. else
  469. {
  470. i-=strlen(sChar);
  471. break;
  472. }
  473. }while(i<nLen);
  474. /*---------------------------------------------*/
  475. }
  476. if(i>=nLen&&bMatch)
  477. return true;
  478. return false;
  479. }
  480. /*---------------------------------------------*/
  481. /*********************************************************************
  482.  *
  483.  *  Func Name  : IsAllIndex
  484.  *
  485.  *  Description: Judge the string is all made up of Index Num Char
  486.  *              
  487.  *
  488.  *  Parameters : sSentence: the original sentence which includes Chinese or Non-Chinese char
  489.  *    
  490.  *  Returns    : the end of the sub-sentence
  491.  *  Author     : Kevin Zhang  
  492.  *  History    : 
  493.  *              1.create 2002-1-24
  494.  *********************************************************************/
  495. bool IsAllIndex(unsigned char *sString)
  496. {
  497. unsigned int nLen=strlen((const char *)sString),i=0;
  498. while(i<nLen-1&&sString[i]==162)
  499. {
  500. i+=2;
  501. }
  502. if(i>=nLen)
  503. return true;
  504.  while(i<nLen&&(sString[i]>'A'-1&&sString[i]<'Z'+1)||(sString[i]>'a'-1&&sString[i]<'z'+1))
  505.  {//single byte number char
  506. i+=1;
  507.  }
  508. if(i<nLen)
  509. return false;
  510. return true;
  511. }
  512. /*********************************************************************
  513.  *
  514.  *  Func Name  : IsAllLetter
  515.  *
  516.  *  Description: Judge the string is all made up of Letter Char
  517.  *              
  518.  *
  519.  *  Parameters : sSentence: the original sentence which includes Chinese or Non-Chinese char
  520.  *    
  521.  *  Returns    : the end of the sub-sentence
  522.  *  Author     : Kevin Zhang  
  523.  *  History    : 
  524.  *              1.create 2002-1-24
  525.  *********************************************************************/
  526. bool IsAllLetter(unsigned char *sString)
  527. {
  528. unsigned int nLen=strlen((const char *)sString),i=0;
  529. while(i<nLen-1&&sString[i]==163&&((sString[i+1]>=193&&sString[i+1]<=218)||(sString[i+1]>=225&&sString[i+1]<=250)))
  530. {
  531. i+=2;
  532. }
  533. if(i<nLen)
  534. return false;
  535. return true;
  536. }
  537. /*********************************************************************
  538.  *
  539.  *  Func Name  : IsAllDelimiter
  540.  *
  541.  *  Description: Judge the string is all made up of Delimiter
  542.  *              
  543.  *
  544.  *  Parameters : sSentence: the original sentence which includes Chinese or Non-Chinese char
  545.  *    
  546.  *  Returns    : the end of the sub-sentence
  547.  *  Author     : Kevin Zhang  
  548.  *  History    : 
  549.  *              1.create 2002-1-24
  550.  *********************************************************************/
  551. bool IsAllDelimiter(unsigned char *sString)
  552. {
  553. unsigned int nLen=strlen((const char *)sString),i=0;
  554. while(i<nLen-1&&(sString[i]==161||sString[i]==163))
  555. {
  556. i+=2;
  557. }
  558. if(i<nLen)
  559. return false;
  560. return true;
  561. }
  562. /*********************************************************************
  563.  *
  564.  *  Func Name  : BinarySearch
  565.  *
  566.  *  Description: Lookup the index of nVal in the table nTable which length is nTableLen
  567.  *
  568.  *  Parameters : nPOS: the POS value
  569.  *
  570.  *  Returns    : the index value
  571.  *  Author     : Kevin Zhang  
  572.  *  History    : 
  573.  *              1.create 2002-1-25
  574.  *********************************************************************/
  575. int BinarySearch(int nVal, int *nTable,int nTableLen)
  576. {
  577. int nStart=0,nEnd=nTableLen-1,nMid=(nStart+nEnd)/2;
  578. while(nStart<=nEnd)//Binary search
  579. {
  580.        if(nTable[nMid]==nVal)
  581.    {
  582. return nMid;//find it
  583.    }
  584.    else if(nTable[nMid]<nVal)
  585.    {
  586.    nStart=nMid+1;
  587.    }
  588.    else
  589.        {
  590.    nEnd=nMid-1;
  591.    }
  592.    nMid=(nStart+nEnd)/2;
  593. }
  594. return -1;//Can not find it;
  595. }
  596. /*********************************************************************
  597.  *
  598.  *  Func Name  : IsForeign
  599.  *
  600.  *  Description: Decide whether the word is not a Non-fereign word
  601.  *
  602.  *  Parameters : sWord: the word
  603.  *
  604.  *  Returns    : the index value
  605.  *  Author     : Kevin Zhang  
  606.  *  History    : 
  607.  *              1.create 2002-1-26
  608.  *********************************************************************/
  609. bool IsForeign(char *sWord)
  610. {
  611.   int nForeignCount=GetForeignCharCount(sWord),nCharCount=strlen(sWord);
  612.   if(nCharCount>2||nForeignCount>=1*nCharCount/2)
  613.   return true;
  614.   return false;
  615. }
  616. /*********************************************************************
  617.  *
  618.  *  Func Name  : IsAllForeign
  619.  *
  620.  *  Description: Decide whether the word is not a Non-fereign word
  621.  *
  622.  *  Parameters : sWord: the word
  623.  *
  624.  *  Returns    : the index value
  625.  *  Author     : Kevin Zhang  
  626.  *  History    : 
  627.  *              1.create 2002-3-25
  628.  *********************************************************************/
  629. bool IsAllForeign(char *sWord)
  630. {
  631.   unsigned int nForeignCount=(unsigned int)GetForeignCharCount(sWord);
  632.   if(2*nForeignCount==strlen(sWord))
  633.   return true;
  634.   return false;
  635. }
  636. /*********************************************************************
  637.  *
  638.  *  Func Name  : IsForeign
  639.  *
  640.  *  Description: Decide whether the word is Chinese Num word
  641.  *
  642.  *  Parameters : sWord: the word
  643.  *
  644.  *  Returns    : the index value
  645.  *  Author     : Kevin Zhang  
  646.  *  History    : 
  647.  *              1.create 2002-1-26
  648.  *********************************************************************/
  649. bool IsAllChineseNum(char *sWord)
  650. {//百分之五点六的人早上八点十八分起床
  651.   unsigned int  k; 
  652.   char tchar[3];
  653.   /* 
  654.   * ----- commented by huangjin@ict.ac.cn 2006-7-21 ------ 
  655.   *
  656.   * char ChineseNum[]="零○一二两三四五六七八九十廿百千万亿壹贰叁肆伍陆柒捌玖拾佰仟∶·./点";//
  657.   *
  658.   */
  659.   /*----Added By huangjin@ict.ac.cn 2006-7-21----*/
  660.   char ChineseNum[]="零○〇一二两三四五六七八九十廿百千万亿壹贰叁肆伍陆柒捌玖拾佰仟∶·./点";//
  661.   /*---------------------------------------------*/
  662.   
  663.   char sPrefix[]="几数第上成";
  664.   for(k = 0; k < strlen(sWord); k+=2)
  665.   {
  666.      strncpy(tchar,sWord+k,2) ;
  667.      tchar[2]='';
  668.  if(strncmp(sWord+k,"分之",4)==0)//百分之五
  669.  {
  670. k+=2;
  671. continue;
  672.  }
  673.  
  674.  if(!CC_Find(ChineseNum, tchar)&&!(k==0&&CC_Find(sPrefix, tchar)))   
  675.  return false;
  676.   }
  677.   /*----Added By huangjin@ict.ac.cn 2006-7-18----*/
  678.   //这里需要说明的是,按上述规则判断的数字有可能是有错误的,比如说
  679.   //本周遇上一道难题 --> 上一 被判断为数词
  680.   //这些前缀的组合是有规律的,例如"上"和"成"应该跟"百千万亿佰仟"
  681.   if(strlen(sWord)>=4)
  682.   {
  683.    strncpy(tchar,sWord,2) ;
  684.    tchar[2]='';
  685.    if(CC_Find("上成", tchar))
  686.    {
  687.    strncpy(tchar,sWord+2,2) ;
  688.    tchar[2]='';
  689.    if(!CC_Find("百千万亿佰仟",tchar))
  690.    {
  691.    return false;
  692.    }
  693.    }
  694.    /*----Added By huangjin@ict.ac.cn 2006-9-17----*/
  695.    if(GetCharCount("∶·./点", sWord)*2==(int)strlen(sWord))// such as ··
  696.    return false;
  697.    /*---------------------------------------------*/
  698.   }
  699.   /*---------------------------------------------*/
  700.   
  701.   return true;
  702. }
  703. /*********************************************************************
  704.  *
  705.  *  Func Name  : GetForeignCharCount
  706.  *
  707.  *  Description: 
  708.  *
  709.  *  Parameters : sWord: the word
  710.  *
  711.  *  Returns    : the index value
  712.  *  Author     : Kevin Zhang  
  713.  *  History    : 
  714.  *              1.create 2002-4-4
  715.  *              2.Modify  2002-5-21
  716.  *********************************************************************/
  717. int GetForeignCharCount(char *sWord)
  718. {
  719.   unsigned int nForeignCount,nCount;
  720.   nForeignCount=GetCharCount(TRANS_ENGLISH,sWord);//English char counnts
  721.   nCount=GetCharCount(TRANS_JAPANESE,sWord);//Japan char counnts
  722.   if(nForeignCount<=nCount)
  723. nForeignCount=nCount;
  724.   nCount=GetCharCount(TRANS_RUSSIAN,sWord);//Russian char counnts
  725.   if(nForeignCount<=nCount)
  726. nForeignCount=nCount;
  727.   return nForeignCount;
  728. }
  729. /*********************************************************************
  730.  *
  731.  *  Func Name  : GetCharCount
  732.  *
  733.  *  Description: Get the count of char which is in sWord and in sCharSet
  734.  *
  735.  *  Parameters : sWord: the word
  736.  * 
  737.  *  Returns    : COUNT
  738.  *  Author     : Kevin Zhang  
  739.  *  History    : 
  740.  *              1.create 2002-5-21
  741.  *********************************************************************/
  742. int GetCharCount(char *sCharSet,char *sWord)
  743. {
  744.   unsigned int  k=0; 
  745.   char tchar[3];
  746.   int nCount=0;
  747.   tchar[2]=0;
  748.   while(k < strlen(sWord))
  749.   {
  750.      tchar[0]=sWord[k];
  751.    tchar[1]=0;
  752.  if(sWord[k]<0)
  753.  {
  754.  tchar[1]=sWord[k+1];
  755.  k+=1;
  756.  }
  757.  k+=1;
  758.  if((tchar[0]<0&&CC_Find(sCharSet, tchar))||strchr(sCharSet,tchar[0]))
  759.           nCount++;
  760.   }
  761.   return nCount;
  762. }
  763. /*********************************************************************
  764.  *
  765.  *  Func Name  : GetForeignCharCount
  766.  *
  767.  *  Description: Return the foreign type 
  768.  *
  769.  *  Parameters : sWord: the word
  770.  *
  771.  *  Returns    : the index value
  772.  *  Author     : Kevin Zhang  
  773.  *  History    : 
  774.  *              1.create 2002-4-4
  775.  *              2.Modify  2002-5-21
  776.  *********************************************************************/
  777. int GetForeignType(char *sWord)
  778. {
  779.   unsigned int nForeignCount,nCount,nType=TT_ENGLISH;
  780.   nForeignCount=GetCharCount(TRANS_ENGLISH,sWord);//English char counnts
  781.   nCount=GetCharCount(TRANS_RUSSIAN,sWord);//Russian char counnts
  782.   if(nForeignCount<nCount)
  783.   {
  784.   nForeignCount=nCount;
  785.   nType=TT_RUSSIAN;
  786.   }
  787.   nCount=GetCharCount(TRANS_JAPANESE,sWord);//Japan char counnts
  788.   if(nForeignCount<nCount)
  789.   {
  790.   nForeignCount=nCount;
  791.   nType=TT_JAPANESE;
  792.   }
  793.   return nType;
  794. }
  795. bool PostfixSplit(char *sWord, char *sWordRet, char *sPostfix)
  796. {
  797. char sSinglePostfix[]=POSTFIX_SINGLE;
  798. char sMultiPostfix[][9]=POSTFIX_MUTIPLE;
  799. unsigned int nPostfixLen=0,nWordLen=strlen(sWord);
  800. int i=0;
  801. while(sMultiPostfix[i][0]!=0&&strncmp(sWord+nWordLen-strlen(sMultiPostfix[i]),sMultiPostfix[i],strlen(sMultiPostfix[i]))!=0)
  802. {//Try to get the postfix of an address
  803. i++;
  804. }
  805. strcpy(sPostfix,sMultiPostfix[i]);
  806. nPostfixLen=strlen(sMultiPostfix[i]);//Get the length of place postfix
  807. if(nPostfixLen==0)
  808. {
  809. sPostfix[2]=0;
  810. strncpy(sPostfix,sWord+nWordLen-2,2);
  811. if(CC_Find(sSinglePostfix,sPostfix))
  812. nPostfixLen=2;
  813. }
  814. strncpy(sWordRet,sWord,nWordLen-nPostfixLen);
  815. sWordRet[nWordLen-nPostfixLen]=0;//Get the place name which have erasing the postfix
  816. sPostfix[nPostfixLen]=0;
  817.     return true;
  818. }
  819. /*----Added By huangjin@ict.ac.cn 2006-9-12----*/
  820. /*********************************************************************
  821.  *
  822.  *  Func Name  : GetChar
  823.  *
  824.  *  Description: Get the first char from sSentence and store it in sRetChar.
  825.  *  The first char could be SBC case or DBC case.
  826.  *
  827.  *  Parameters : const char *sSentence, char *sRetChar
  828.  *
  829.  *  Returns    : The length of sRetChar, exclude the NULL end, should be 0, 1 or 2
  830.  *  Author     : Huang Jin  
  831.  *  History    : 
  832.  *              1.create 2006-09-12
  833.  *        
  834.  *********************************************************************/
  835. unsigned int GetChar(const char *sSentence, char *sRetChar)
  836. {
  837. unsigned int nLen=0;
  838. if(!sSentence||!sRetChar)
  839. return nLen;
  840. sRetChar[nLen++]=sSentence[0];
  841. if(sRetChar[0]<0)
  842. {
  843. sRetChar[nLen++]=sSentence[1];
  844. }
  845. sRetChar[nLen]='';
  846. return nLen;   
  847. }
  848. /*********************************************************************
  849.  *
  850.  *  Func Name  : IsChineseNumCadidate
  851.  *
  852.  *  Description: Decide wether the word is Chinese Number Cadidate
  853.  *
  854.  *  Parameters : const char *sChar
  855.  *
  856.  *  Returns    : return true if the word is Chinese Number Cadidate, otherwise false
  857.  *  Author     : Huang Jin  
  858.  *  History    : 
  859.  *              1.create 2006-09-12
  860.  *        
  861.  *********************************************************************/
  862. bool IsChineseNumCadidate(const char* sChar)
  863. {
  864. static const char ChineseNumCadidate[] = {"零○〇一二两三四五六七八九十廿卅卌百千万亿兆壹贰叁肆伍陆柒捌玖拾佰仟"};
  865. static const char OtherChineseNumCadidate[] = {"点"};
  866. return (CC_Find(ChineseNumCadidate,sChar) || CC_Find(OtherChineseNumCadidate,sChar));
  867. }
  868. unsigned int ChineseNumRecognize( const char* sNumCadidate, const char* sRestSentence )
  869. {
  870. if(!sNumCadidate)
  871. return -1;
  872. int nEnd = strlen(sNumCadidate);
  873. if(nEnd<3) //at least two words
  874. return -1;
  875.     char sFirstChar[3]="";
  876. char sLastChar[3]="";
  877. GetChar(sNumCadidate,sFirstChar);
  878.     GetChar(sNumCadidate+nEnd-2,sLastChar);
  879. if(CC_Find("分点",sFirstChar))//"分之" and "点" shouldn't be at the beginning
  880. return -1;
  881. if(CC_Find("点",sLastChar))
  882. {
  883. nEnd-=2;
  884. }
  885. /*----Added By huangjin@ict.ac.cn 2006-9-14----*/
  886. else if(nEnd>4&&!strcmp("之",sLastChar))//"分之"shouldn't be at the endning
  887. {
  888. nEnd-=4;
  889. }
  890. /*---------------------------------------------*/
  891. else if(sRestSentence&&*sRestSentence)
  892. {
  893. char sRestChar[3]="";
  894. GetChar(sRestSentence,sRestChar);
  895. if(CC_Find("千",sLastChar))
  896. {
  897. if(CC_Find("米瓦里克卡赫",sRestChar))
  898. {
  899. nEnd-=2;
  900. }
  901. }
  902. else
  903. {//五点十 分
  904. char* pFind=CC_Find(sNumCadidate,"点");
  905. if(pFind&&!strcmp(sRestChar,"分"))
  906. {
  907. nEnd=nEnd-strlen(pFind)+2;
  908. }
  909. }
  910. }
  911. return nEnd;
  912. }
  913. /*---------------------------------------------*/