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

多国语言处理

开发平台:

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: Dictionary.cpp
  24.  * Abstract:
  25.  *           implementation of the CDictionary class.
  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 "Dictionary.h"
  35. #include "Utility.h"
  36. #include <string.h>
  37. #include <stdlib.h>
  38. #include <malloc.h>
  39. #include <stdio.h>
  40. //////////////////////////////////////////////////////////////////////
  41. // Construction/Destruction
  42. //////////////////////////////////////////////////////////////////////
  43. CDictionary::CDictionary()
  44. {
  45.   //initilization
  46.   memset(m_IndexTable,0,sizeof(m_IndexTable));
  47.   m_pModifyTable=NULL;
  48.   /*----Added By huangjin@ict.ac.cn 2006-9-12----*/
  49.   m_bAvailable=false;
  50.   /*---------------------------------------------*/
  51. }
  52. CDictionary::~CDictionary()
  53. {
  54. /* 
  55. * ----- commented by huangjin@ict.ac.cn 2006-5-29 ------ 
  56. * for(int i=0;i<CC_NUM;i++)
  57. * {//delete the memory of word item array in the dictionary
  58. * for(int j=0;j<m_IndexTable[i].nCount;j++)
  59. * delete m_IndexTable[i].pWordItemHead[j].sWord;
  60. *
  61. * delete [] m_IndexTable[i].pWordItemHead;
  62. *}
  63.     * DelModified();
  64. *
  65. */
  66. /*----Added By huangjin@ict.ac.cn 2006-5-29----*/
  67. ClearDictionary();
  68. /*---------------------------------------------*/
  69. }
  70. /*********************************************************************
  71.  *
  72.  *  Func Name  : Load
  73.  *
  74.  *  Description: Load the dictionary from the file .dct
  75.  *              
  76.  *
  77.  *  Parameters : sFilename: the file name
  78.  *
  79.  *  Returns    : success or fail
  80.  *  Author     : Kevin Zhang  
  81.  *  History    : 
  82.  *              1.create 2002-1-9
  83.  *********************************************************************/
  84. bool CDictionary::Load(char *sFilename,bool bReset)
  85. {
  86.    FILE *fp;
  87.    int i,j,nBuffer[3];
  88.    if((fp=fopen(sFilename,"rb"))==NULL)
  89.    return false;//fail while opening the file
  90.    
  91.    //Release the memory for new files
  92.    /* 
  93. * ----- commented by huangjin@ict.ac.cn 2006-5-29 ------ 
  94. * for(int i=0;i<CC_NUM;i++)
  95. * {//delete the memory of word item array in the dictionary
  96. * for(int j=0;j<m_IndexTable[i].nCount;j++)
  97. * delete m_IndexTable[i].pWordItemHead[j].sWord;
  98. *
  99. * delete [] m_IndexTable[i].pWordItemHead;
  100. *}
  101.     * DelModified();
  102. *
  103. */
  104.    /*----Added By huangjin@ict.ac.cn 2006-5-29----*/
  105. ClearDictionary();
  106. /*---------------------------------------------*/
  107.    for(i=0;i<CC_NUM;i++)
  108.    {
  109.    fread(&(m_IndexTable[i].nCount),sizeof(int),1,fp);
  110.        if(m_IndexTable[i].nCount>0)
  111.      m_IndexTable[i].pWordItemHead=new WORD_ITEM[m_IndexTable[i].nCount];
  112.    else 
  113.    {
  114.    m_IndexTable[i].pWordItemHead=0;
  115.    continue;
  116.    }
  117.        j=0;
  118.    while(j<m_IndexTable[i].nCount)
  119.    {
  120.          fread(nBuffer,sizeof(int),3,fp);
  121.          m_IndexTable[i].pWordItemHead[j].sWord=new char[nBuffer[1]+1];
  122.     if(nBuffer[1])//String length is more than 0
  123.  {
  124.  fread(m_IndexTable[i].pWordItemHead[j].sWord,sizeof(char),nBuffer[1],fp);
  125.  }
  126.  m_IndexTable[i].pWordItemHead[j].sWord[nBuffer[1]]=0;
  127.         if(bReset)//Reset the frequency
  128.           m_IndexTable[i].pWordItemHead[j].nFrequency=0;
  129.  else
  130.               m_IndexTable[i].pWordItemHead[j].nFrequency=nBuffer[0];
  131.  m_IndexTable[i].pWordItemHead[j].nWordLen=nBuffer[1];
  132.  m_IndexTable[i].pWordItemHead[j].nHandle=nBuffer[2];
  133.    j+=1;//Get next item in the original table.
  134.    }
  135.    }
  136.    fclose(fp);
  137.    /*----Added By huangjin@ict.ac.cn 2006-9-12----*/
  138.    m_bAvailable=true;
  139.    /*---------------------------------------------*/
  140.    return true;
  141. }
  142. /*********************************************************************
  143.  *
  144.  *  Func Name  : Save
  145.  *
  146.  *  Description: Save the dictionary as the file .dct
  147.  *              
  148.  *
  149.  *  Parameters : sFilename: the file name
  150.  *
  151.  *  Returns    : success or fail
  152.  *  Author     : Kevin Zhang  
  153.  *  History    : 
  154.  *              1.create 2002-1-9
  155.  *********************************************************************/
  156. bool CDictionary::Save(char *sFilename)
  157. {
  158.    FILE *fp;
  159.    int i,j,nCount,nBuffer[3];
  160.    PWORD_CHAIN pCur;
  161.    if((fp=fopen(sFilename,"wb"))==NULL)
  162.    return false;//fail while opening the file
  163.    for(i=0;i<CC_NUM;i++)
  164.    {
  165.    pCur=NULL;
  166.    if(m_pModifyTable)
  167.    {//Modification made
  168.    nCount=m_IndexTable[i].nCount+m_pModifyTable[i].nCount-m_pModifyTable[i].nDelete;
  169.    fwrite(&nCount,sizeof(int),1,fp);
  170.    pCur=m_pModifyTable[i].pWordItemHead;
  171.    j=0;
  172.    while(pCur!=NULL&&j<m_IndexTable[i].nCount)
  173.    {//Output to the file after comparision
  174.    if(strcmp(pCur->data.sWord,m_IndexTable[i].pWordItemHead[j].sWord)<0||(strcmp(pCur->data.sWord,m_IndexTable[i].pWordItemHead[j].sWord)==0&&pCur->data.nHandle<m_IndexTable[i].pWordItemHead[j].nHandle))
  175.    {//Output the modified data to the file
  176.  nBuffer[0]=pCur->data.nFrequency;
  177.          nBuffer[1]=pCur->data.nWordLen;
  178.      nBuffer[2]=pCur->data.nHandle;
  179.                  fwrite(nBuffer,sizeof(int),3,fp);
  180.  if(nBuffer[1])//String length is more than 0
  181.           fwrite(pCur->data.sWord,sizeof(char),nBuffer[1],fp);
  182.                  pCur=pCur->next;//Get next item in the modify table.
  183.    }
  184.    else if(m_IndexTable[i].pWordItemHead[j].nFrequency==-1)
  185.    {//The item has been removed,so skip it
  186.    j+=1;
  187.    }
  188.    else if(strcmp(pCur->data.sWord,m_IndexTable[i].pWordItemHead[j].sWord)>0||(strcmp(pCur->data.sWord,m_IndexTable[i].pWordItemHead[j].sWord)==0&&pCur->data.nHandle>m_IndexTable[i].pWordItemHead[j].nHandle))
  189.    {//Output the index table data to the file
  190.  nBuffer[0]=m_IndexTable[i].pWordItemHead[j].nFrequency;
  191.  nBuffer[1]=m_IndexTable[i].pWordItemHead[j].nWordLen;
  192.  nBuffer[2]=m_IndexTable[i].pWordItemHead[j].nHandle;
  193.  fwrite(nBuffer,sizeof(int),3,fp);
  194.  if(nBuffer[1])//String length is more than 0
  195.    fwrite(m_IndexTable[i].pWordItemHead[j].sWord,sizeof(char),nBuffer[1],fp);
  196.  j+=1;//Get next item in the original table.
  197.    }
  198.    }
  199.    if(j<m_IndexTable[i].nCount)
  200.    {
  201.    while(j<m_IndexTable[i].nCount)
  202.    {
  203.    if(m_IndexTable[i].pWordItemHead[j].nFrequency!=-1)
  204.    {//Has been deleted
  205.  nBuffer[0]=m_IndexTable[i].pWordItemHead[j].nFrequency;
  206.  nBuffer[1]=m_IndexTable[i].pWordItemHead[j].nWordLen;
  207.  nBuffer[2]=m_IndexTable[i].pWordItemHead[j].nHandle;
  208.  fwrite(nBuffer,sizeof(int),3,fp);
  209.  if(nBuffer[1])//String length is more than 0
  210.    fwrite(m_IndexTable[i].pWordItemHead[j].sWord,sizeof(char),nBuffer[1],fp);
  211.    }
  212.    j+=1;//Get next item in the original table.
  213.    }
  214.    }
  215.    else////No Modification
  216.    while(pCur!=NULL)//Add the rest data to the file.
  217.    {
  218.  nBuffer[0]=pCur->data.nFrequency;
  219.          nBuffer[1]=pCur->data.nWordLen;
  220.      nBuffer[2]=pCur->data.nHandle;
  221.                  fwrite(nBuffer,sizeof(int),3,fp);
  222.  if(nBuffer[1])//String length is more than 0
  223.    fwrite(pCur->data.sWord,sizeof(char),nBuffer[1],fp);
  224.                  pCur=pCur->next;//Get next item in the modify table.
  225.    }
  226.    }
  227.    else
  228.    {
  229.    fwrite(&m_IndexTable[i].nCount,sizeof(int),1,fp);
  230.    //write to the file
  231.            j=0;  
  232.    while(j<m_IndexTable[i].nCount)
  233.    {
  234.  nBuffer[0]=m_IndexTable[i].pWordItemHead[j].nFrequency;
  235.      nBuffer[1]=m_IndexTable[i].pWordItemHead[j].nWordLen;
  236.  nBuffer[2]=m_IndexTable[i].pWordItemHead[j].nHandle;
  237.              fwrite(nBuffer,sizeof(int),3,fp);
  238.  if(nBuffer[1])//String length is more than 0
  239.    fwrite(m_IndexTable[i].pWordItemHead[j].sWord,sizeof(char),nBuffer[1],fp);
  240.    j+=1;//Get next item in the original table.
  241.    }
  242.    }
  243.    }
  244.    fclose(fp);
  245.    return true;
  246. }
  247. /*********************************************************************
  248.  *
  249.  *  Func Name  : AddItem
  250.  *
  251.  *  Description: Add a word item to the dictionary
  252.  *              
  253.  *
  254.  *  Parameters : sWord: the word
  255.  *               nHandle:the handle number
  256.  *               nFrequency: the frequency
  257.  *  Returns    : success or fail
  258.  *  Author     : Kevin Zhang  
  259.  *  History    : 
  260.  *              1.create 2002-1-9
  261.  *********************************************************************/
  262. bool CDictionary::AddItem(char *sWord, int nHandle,int nFrequency)
  263. {
  264.    char sWordAdd[WORD_MAXLENGTH-2];
  265.    int nPos,nFoundPos;
  266.    PWORD_CHAIN pRet,pTemp,pNext;
  267.    int i=0;
  268.    if(!PreProcessing(sWord, &nPos,sWordAdd,true))
  269.    return false;
  270.    if(FindInOriginalTable(nPos,sWordAdd,nHandle,&nFoundPos))
  271.    {//The word exists in the original table, so add the frequency
  272.     //Operation in the index table and its items 
  273.        if(m_IndexTable[nPos].pWordItemHead[nFoundPos].nFrequency==-1)
  274.    {//The word item has been removed
  275.       m_IndexTable[nPos].pWordItemHead[nFoundPos].nFrequency=nFrequency;
  276.         if(!m_pModifyTable)//Not prepare the buffer
  277.   {
  278.    m_pModifyTable=new MODIFY_TABLE[CC_NUM];
  279.    memset(m_pModifyTable,0,CC_NUM*sizeof(MODIFY_TABLE));
  280.   }
  281.   m_pModifyTable[nPos].nDelete-=1;
  282.    }
  283.    else
  284.   m_IndexTable[nPos].pWordItemHead[nFoundPos].nFrequency+=nFrequency;
  285.    return true;
  286.    }
  287.    //The items not exists in the index table.
  288.    //As following, we have to find the item whether exists in the modify data region
  289.    //If exists, change the frequency .or else add a item
  290.    if(!m_pModifyTable)//Not prepare the buffer
  291.    {
  292.    m_pModifyTable=new MODIFY_TABLE[CC_NUM];
  293.    memset(m_pModifyTable,0,CC_NUM*sizeof(MODIFY_TABLE));
  294.    }
  295.    if(FindInModifyTable(nPos,sWordAdd,nHandle,&pRet))
  296.    {
  297.    if(pRet!=NULL)
  298.    pRet=pRet->next;
  299.    else
  300.    pRet=m_pModifyTable[nPos].pWordItemHead;
  301.    pRet->data.nFrequency+=nFrequency;
  302.    return true;
  303.    }
  304.    //find the proper position to add the word to the modify data table and link
  305.    pTemp=new WORD_CHAIN;//Allocate the word chain node
  306.    if(pTemp==NULL)//Allocate memory failure
  307.    return false;
  308.    memset(pTemp,0,sizeof(WORD_CHAIN));//init it with 0
  309.    pTemp->data.nHandle=nHandle;//store the handle 
  310.    pTemp->data.nWordLen=strlen(sWordAdd);
  311.    pTemp->data.sWord=new char[1+pTemp->data.nWordLen];
  312.    strcpy(pTemp->data.sWord,sWordAdd);
  313.    pTemp->data.nFrequency=nFrequency;
  314.    pTemp->next=NULL;   
  315.    if(pRet!=NULL)
  316.    {
  317.    pNext=pRet->next;//Get the next item before the current item
  318.    pRet->next=pTemp;//link the node to the chain
  319.    }
  320.    else
  321.    {
  322.    pNext=m_pModifyTable[nPos].pWordItemHead;
  323.    m_pModifyTable[nPos].pWordItemHead=pTemp;//Set the pAdd as the head node
  324.    }
  325.    pTemp->next=pNext;//Very important!!!! or else it will lose some node
  326.    //Modify in 2001-10-29
  327.    m_pModifyTable[nPos].nCount++;//the number increase by one
  328.    return true;
  329. }
  330. bool CDictionary::DelItem(char *sWord,int nHandle)
  331. {
  332.    char sWordDel[WORD_MAXLENGTH-2];
  333.    int nPos,nFoundPos,nTemp;
  334.    PWORD_CHAIN pPre,pTemp,pCur;
  335.    if(!PreProcessing(sWord, &nPos,sWordDel))
  336.    return false;
  337.    if(FindInOriginalTable(nPos,sWordDel,nHandle,&nFoundPos))
  338.    {
  339.        if(!m_pModifyTable)//Not prepare the buffer
  340.    {
  341.    m_pModifyTable=new MODIFY_TABLE[CC_NUM];
  342.    memset(m_pModifyTable,0,CC_NUM*sizeof(MODIFY_TABLE));
  343.    }
  344.        m_IndexTable[nPos].pWordItemHead[nFoundPos].nFrequency=-1;
  345.    m_pModifyTable[nPos].nDelete+=1;
  346.    if(nHandle==-1)//Remove all items which word is sWordDel,ignoring the handle
  347.    {
  348. /*    nTemp=nFoundPos-1;//Check its previous position
  349.    while(nTemp>0&&strcmp(m_IndexTable[nPos].pWordItemHead[nFoundPos].sWord,sWordDel)==0)
  350.    {
  351. m_IndexTable[nPos].pWordItemHead[nTemp].nFrequency=-1;
  352. m_pModifyTable[nPos].nDelete+=1;
  353. nTemp-=1;
  354.    }
  355. */    nTemp=nFoundPos+1;//Check its previous position
  356.    while(nTemp<m_IndexTable[nPos].nCount&&strcmp(m_IndexTable[nPos].pWordItemHead[nFoundPos].sWord,sWordDel)==0)
  357.    {
  358. m_IndexTable[nPos].pWordItemHead[nTemp].nFrequency=-1;
  359. m_pModifyTable[nPos].nDelete+=1;
  360. nTemp+=1;
  361.    }
  362.    }
  363.    return true;
  364.    }
  365.    //Operation in the modify table and its items 
  366.    if(FindInModifyTable(nPos,sWordDel,nHandle,&pPre))
  367.    {
  368.      pCur=m_pModifyTable[nPos].pWordItemHead;
  369.      if(pPre!=NULL)
  370.  pCur=pPre->next;
  371.          while(pCur!=NULL && _stricmp(pCur->data.sWord,sWordDel)==0&&(pCur->data.nHandle==nHandle||nHandle<0))
  372.  {
  373.  pTemp=pCur;
  374.       if(pPre!=NULL)//pCur is the first item
  375.  pPre->next=pCur->next;
  376.  else
  377.  m_pModifyTable[nPos].pWordItemHead=pCur->next;
  378.  pCur=pCur->next;
  379.  /* 
  380.  * ----- commented by huangjin@ict.ac.cn 2006-5-29 ------ 
  381.  * 
  382.  *  delete pTemp->data.sWord;//Delete the word
  383.  *
  384.  */  
  385.  /*----Added By huangjin@ict.ac.cn 2006-5-29----*/
  386.  delete []pTemp->data.sWord;//Delete the word
  387.  pTemp->data.sWord=NULL;
  388.  /*---------------------------------------------*/
  389.  delete pTemp;
  390.  /*----Added By huangjin@ict.ac.cn 2006-9-18----*/
  391.  m_pModifyTable[nPos].nCount--;
  392.  /*---------------------------------------------*/
  393.  }  
  394.    return true;
  395.    }
  396.    return false;
  397. }
  398. bool CDictionary::DelModified()
  399. {
  400.   PWORD_CHAIN pTemp,pCur;
  401.   if(!m_pModifyTable)
  402.   return true;
  403.   for(int i=0;i<CC_NUM;i++)
  404.   {
  405.       pCur=m_pModifyTable[i].pWordItemHead;
  406.   while(pCur!=NULL)
  407.   {
  408.   pTemp=pCur;
  409.   pCur=pCur->next;
  410.   /* 
  411.   * ----- commented by huangjin@ict.ac.cn 2006-5-29 ------ 
  412.   * 
  413.   *  delete pTemp->data.sWord;//Delete the word
  414.   *
  415.   */  
  416.   /*----Added By huangjin@ict.ac.cn 2006-5-29----*/
  417.   delete []pTemp->data.sWord;//Delete the word
  418.   pTemp->data.sWord=NULL;
  419.   /*---------------------------------------------*/
  420.   delete pTemp;
  421.   }
  422.   }
  423.   delete [] m_pModifyTable;
  424.   m_pModifyTable=NULL;
  425.   return true;
  426. }
  427. bool CDictionary::IsExist(char *sWord,  int nHandle)
  428. {
  429.    char sWordFind[WORD_MAXLENGTH-2];
  430.    int nPos;
  431.    if(!PreProcessing(sWord, &nPos,sWordFind))
  432.    return false;
  433.    return(FindInOriginalTable(nPos,sWordFind,nHandle)||FindInModifyTable(nPos,sWordFind,nHandle));
  434. }
  435. bool CDictionary::GetHandle(char *sWord,int *pnCount,int *pnHandle,int *pnFrequency)
  436. {
  437.    char sWordGet[WORD_MAXLENGTH-2];
  438.    int nPos,nFoundPos,nTemp;
  439.    PWORD_CHAIN pPre,pCur;
  440.    *pnCount=0;
  441.    if(!PreProcessing(sWord, &nPos,sWordGet))
  442.    return false;
  443.    if(FindInOriginalTable(nPos,sWordGet,-1,&nFoundPos))
  444.    {
  445.        pnHandle[*pnCount]=m_IndexTable[nPos].pWordItemHead[nFoundPos].nHandle;
  446.    pnFrequency[*pnCount]=m_IndexTable[nPos].pWordItemHead[nFoundPos].nFrequency;
  447.    *pnCount+=1;
  448. /*    nTemp=nFoundPos-1;//Check its previous position
  449.    while(nTemp>0&&strcmp(m_IndexTable[nPos].pWordItemHead[nTemp].sWord,sWordGet)==0)
  450.    {
  451.    pnHandle[*pnCount]=m_IndexTable[nPos].pWordItemHead[nTemp].nHandle;
  452.    pnFrequency[*pnCount]=m_IndexTable[nPos].pWordItemHead[nTemp].nFrequency;
  453.    *pnCount+=1;
  454.        nTemp-=1;
  455.    }
  456. */    nTemp=nFoundPos+1;//Check its previous position
  457.    while(nTemp<m_IndexTable[nPos].nCount&&strcmp(m_IndexTable[nPos].pWordItemHead[nTemp].sWord,sWordGet)==0)
  458.    {
  459.    pnHandle[*pnCount]=m_IndexTable[nPos].pWordItemHead[nTemp].nHandle;
  460.    pnFrequency[*pnCount]=m_IndexTable[nPos].pWordItemHead[nTemp].nFrequency;
  461.    *pnCount+=1;
  462.    nTemp+=1;
  463.    }
  464.    return true;
  465.    }
  466.    //Operation in the index table and its items 
  467.    if(FindInModifyTable(nPos,sWordGet,-1,&pPre))
  468.    {
  469.      pCur=m_pModifyTable[nPos].pWordItemHead;
  470.      if(pPre!=NULL)
  471.  pCur=pPre->next;
  472.          while(pCur!=NULL && _stricmp(pCur->data.sWord,sWordGet)==0)
  473.  {
  474.  pnHandle[*pnCount]=pCur->data.nHandle;
  475.  pnFrequency[*pnCount]=pCur->data.nFrequency;
  476.  *pnCount+=1;
  477.    pCur=pCur->next;
  478.  }
  479.    return true;
  480.    }
  481.    return false;
  482. }
  483. /*********************************************************************
  484.  *
  485.  *  Func Name  : FindInOriginalTable
  486.  *
  487.  *  Description: judge the word and handle exist in the inner table and its items
  488.  *              
  489.  *
  490.  *  Parameters : nInnerCode: the inner code of the first CHines char
  491.  *               sWord: the word
  492.  *               nHandle:the handle number
  493.  *               *nPosRet:the position which node is matched
  494.  *
  495.  *  Returns    : success or fail
  496.  *  Author     : Kevin Zhang  
  497.  *  History    : 
  498.  *              1.create 2002-1-9
  499.  *********************************************************************/
  500. bool CDictionary::FindInOriginalTable(int nInnerCode,char *sWord,int nHandle,int *nPosRet)
  501. {
  502. /*----Added By huangjin@ict.ac.cn 2006-9-17----*/
  503. if(nInnerCode<0)
  504. return false;
  505. /*---------------------------------------------*/
  506.     PWORD_ITEM pItems=m_IndexTable[nInnerCode].pWordItemHead;
  507. int nStart=0,nEnd=m_IndexTable[nInnerCode].nCount-1,nMid=(nStart+nEnd)/2,nCount=0,nCmpValue;
  508. while(nStart<=nEnd)//Binary search
  509. {
  510.        nCmpValue=strcmp(pItems[nMid].sWord,sWord);
  511.        if(nCmpValue==0&&(pItems[nMid].nHandle==nHandle||nHandle==-1))
  512.    {
  513.    if(nPosRet)
  514.    {
  515.    if(nHandle==-1)//Not very strict match
  516.    {//Add in 2002-1-28
  517.    nMid-=1;
  518.    while(nMid>=0&&strcmp(pItems[nMid].sWord,sWord)==0)
  519.    //Get the first item which match the current word
  520.    nMid--;
  521.                    if(nMid<0||strcmp(pItems[nMid].sWord,sWord)!=0)
  522.    nMid++;
  523.    }
  524.    /* 
  525. * ----- commented by huangjin@ict.ac.cn 2006-9-12 ------ 
  526. *
  527. * if(nPosRet)
  528. *
  529. */
  530.     *nPosRet=nMid;       
  531. /* 
  532. * ----- commented by huangjin@ict.ac.cn 2006-9-12 ------ 
  533. *
  534. * return true;
  535. *
  536. */    
  537.    }
  538.     /* 
  539. * ----- commented by huangjin@ict.ac.cn 2006-9-12 ------ 
  540. *
  541. * if(nPosRest)
  542. * *nPosRet=nMid;
  543. *
  544.    */         
  545. return true;//find it
  546.    }
  547.    else if(nCmpValue<0||(nCmpValue==0&&pItems[nMid].nHandle<nHandle&&nHandle!=-1))
  548.    {
  549.    nStart=nMid+1;
  550.    }
  551.    else if(nCmpValue>0||(nCmpValue==0&&pItems[nMid].nHandle>nHandle&&nHandle!=-1))
  552.        {
  553.    nEnd=nMid-1;
  554.    }
  555.    nMid=(nStart+nEnd)/2;
  556. }
  557.     if(nPosRet)
  558. {
  559. //Get the previous position
  560. *nPosRet=nMid-1;
  561. }
  562. return false;
  563. }
  564. /*********************************************************************
  565.  *
  566.  *  Func Name  : FindInModifyTable
  567.  *
  568.  *  Description: judge the word and handle exist in the modified table and its items
  569.  *              
  570.  *
  571.  *  Parameters : nInnerCode: the inner code of the first CHines char
  572.  *               sWord: the word
  573.  *               nHandle:the handle number
  574.  *               *pFindRet: the node found
  575.  *
  576.  *  Returns    : success or fail
  577.  *  Author     : Kevin Zhang  
  578.  *  History    : 
  579.  *              1.create 2002-1-9
  580.  *********************************************************************/
  581. bool CDictionary::FindInModifyTable(int nInnerCode,char *sWord,int nHandle,PWORD_CHAIN *pFindRet)
  582. {
  583. /*----Added By huangjin@ict.ac.cn 2006-9-17----*/
  584. if(nInnerCode<0)
  585. return false;
  586. /*---------------------------------------------*/
  587.    PWORD_CHAIN pCur,pPre;
  588.    if(m_pModifyTable==NULL)//empty
  589.    return false;
  590.    pCur=m_pModifyTable[nInnerCode].pWordItemHead;
  591.    pPre=NULL;
  592.    while(pCur!=NULL&&(_stricmp(pCur->data.sWord,sWord)<0||(_stricmp(pCur->data.sWord,sWord)==0&&pCur->data.nHandle<nHandle)))
  593.    //sort the link chain as alphabet
  594.    {
  595.        pPre=pCur;
  596.    pCur=pCur->next;
  597.    }
  598.    if(pFindRet)
  599.      *pFindRet=pPre;
  600.    if(pCur!=NULL && _stricmp(pCur->data.sWord,sWord)==0&&(pCur->data.nHandle==nHandle||nHandle<0))
  601.    {//The node exists, delete the node and return 
  602.    return true;
  603.    }
  604.    return false;
  605. }
  606. /*********************************************************************
  607.  *
  608.  *  Func Name  : GetWordType
  609.  *
  610.  *  Description: Get the type of word
  611.  *              
  612.  *
  613.  *  Parameters : sWord: the word
  614.  *  Returns    : the type
  615.  *  Author     : Kevin Zhang  
  616.  *  History    : 
  617.  *              1.create 2002-1-9
  618.  *********************************************************************/
  619. int CDictionary::GetWordType(char *sWord)
  620. {
  621.    int nType=charType((unsigned char *)sWord),nLen=strlen(sWord);
  622.    if(nLen>0&&nType==CT_CHINESE&&IsAllChinese((unsigned char *)sWord))
  623.    return WT_CHINESE;//Chinese word
  624.    else if(nLen>0&&nType==CT_DELIMITER)
  625.        return WT_DELIMITER;//Delimiter
  626.    else
  627.    return WT_OTHER;//other invalid
  628. }
  629. /*********************************************************************
  630.  *
  631.  *  Func Name  : PreProcessing
  632.  *
  633.  *  Description: Get the type of word
  634.  *              
  635.  *
  636.  *  Parameters : sWord: the word
  637.  *  Returns    : the type
  638.  *  Author     : Kevin Zhang  
  639.  *  History    : 
  640.  *              1.create 2002-1-9
  641.  *********************************************************************/
  642. bool CDictionary::PreProcessing(char *sWord, int *nId, char *sWordRet,bool bAdd)
  643. {
  644.    //Position for the delimeters
  645.    int nType=charType((unsigned char *)sWord),nLen=strlen(sWord);
  646.    int nEnd=nLen-1,nBegin=0;
  647.    if(nLen==0)
  648.    return false;
  649.    while(nEnd>=0&&sWord[nEnd]==' ')
  650. nEnd-=1;
  651.    while(nBegin<=nEnd&&sWord[nBegin]==' ')
  652. nBegin+=1;
  653.    if(nBegin>nEnd)
  654.    return false;
  655.    if(nEnd!=nLen-1||nBegin!=0)
  656.    {
  657.    strncpy(sWord,sWord+nBegin,nEnd-nBegin+1);
  658.    sWord[nEnd-nBegin+1]=0;
  659.    }
  660. /*
  661.    if((bAdd||strlen(sWord)>4)&&IsAllChineseNum(sWord))
  662.    {  //Only convert the Chinese Num to 3755 while 
  663.       //Get the inner code of the first Chinese Char
  664.        strcpy(sWord,"五十八");
  665.    }
  666. */   
  667.    if(nType==CT_CHINESE)//&&IsAllChinese((unsigned char *)sWord)
  668.    {//Chinese word
  669.    *nId=CC_ID(sWord[0],sWord[1]);
  670.    //Get the inner code of the first Chinese Char
  671. strcpy(sWordRet,&sWord[2]);//store the word,not store the first Chinese Char
  672. return true;
  673.    }
  674. /* if(nType==CT_NUM&&IsAllNum((unsigned char *)sWord))
  675.    {
  676.    *nId=3756;
  677.        //Get the inner code of the first Chinese Char
  678.        sWordRet[0]=0;//store the word,not store the first Chinese Char
  679.    return true;
  680.    }
  681. */ if(nType==CT_DELIMITER)
  682.    {//Delimiter
  683.    *nId=3755;
  684.        //Get the inner code of the first Chinese Char
  685.        strcpy(sWordRet,sWord);//store the word,not store the first Chinese Char
  686.    return true;
  687.    }
  688. /*
  689.    if(nType==CT_LETTER&&IsAllLetter((unsigned char *)sWord))
  690.    {
  691.    *nId=3757;
  692.        //Get the inner code of the first Chinese Char
  693.        sWordRet[0]=0;//store the word,not store the first Chinese Char
  694.    return true;
  695.    }
  696.    if(nType==CT_SINGLE&&IsAllSingleByte((unsigned char *)sWord))
  697.    {
  698.    *nId=3758;
  699.        //Get the inner code of the first Chinese Char
  700.        sWordRet[0]=0;//store the word,not store the first Chinese Char
  701.    return true;
  702.    }
  703.    if(nType==CT_INDEX&&IsAllIndex((unsigned char *)sWord))
  704.    {
  705.    *nId=3759;
  706.        //Get the inner code of the first Chinese Char
  707.        sWordRet[0]=0;//store the word,not store the first Chinese Char
  708.    return true;
  709.    }
  710. */
  711.    return false;//other invalid
  712. }
  713. /*********************************************************************
  714.  *
  715.  *  Func Name  : MergePOS
  716.  *
  717.  *  Description: Merge all the POS into nHandle,
  718.  *              just get the word in the dictionary and set its Handle as nHandle
  719.  *              
  720.  *
  721.  *  Parameters : nHandle: the only handle which will be attached to the word
  722.  *  Returns    : the type
  723.  *  Author     : Kevin Zhang  
  724.  *  History    : 
  725.  *              1.create 2002-1-21
  726.  *********************************************************************/
  727. bool CDictionary::MergePOS(int nHandle)
  728. {
  729.     int i,j,nCompare;
  730. char sWordPrev[WORD_MAXLENGTH];
  731. PWORD_CHAIN pPre,pCur,pTemp;
  732.     if(!m_pModifyTable)//Not prepare the buffer
  733.     {
  734.    m_pModifyTable=new MODIFY_TABLE[CC_NUM];
  735.    memset(m_pModifyTable,0,CC_NUM*sizeof(MODIFY_TABLE));
  736.     }
  737. for( i=0;i<CC_NUM;i++)//Operation in the index table
  738. {//delete the memory of word item array in the dictionary
  739. sWordPrev[0]=0;//Set empty
  740. for(j=0;j<m_IndexTable[i].nCount;j++)
  741. {
  742. nCompare=_stricmp(sWordPrev,m_IndexTable[i].pWordItemHead[j].sWord);
  743.             if((j==0||nCompare<0)&&m_IndexTable[i].pWordItemHead[j].nFrequency!=-1)
  744. {//Need to modify its handle
  745.     m_IndexTable[i].pWordItemHead[j].nHandle=nHandle;//Change its handle
  746. strcpy(sWordPrev,m_IndexTable[i].pWordItemHead[j].sWord);//Refresh previous Word
  747. }
  748. else if(nCompare==0&&m_IndexTable[i].pWordItemHead[j].nFrequency!=-1)
  749. {//Need to delete when not delete and same as previous word
  750. m_IndexTable[i].pWordItemHead[j].nFrequency=-1;//Set delete flag
  751. m_pModifyTable[i].nDelete+=1;//Add the number of being deleted
  752. }
  753. }
  754. }
  755. for( i=0;i<CC_NUM;i++)//Operation in the modify table
  756. {
  757.  pPre=NULL;
  758.      pCur=m_pModifyTable[i].pWordItemHead;
  759.  sWordPrev[0]=0;//Set empty
  760.          while(pCur!=NULL)
  761.  {
  762.  if(_stricmp(pCur->data.sWord,sWordPrev)>0)
  763.  {//The new word
  764. pCur->data.nHandle=nHandle;//Chang its handle
  765. strcpy(sWordPrev,pCur->data.sWord);//Set new previous word
  766. pPre=pCur;//New previous pointer
  767. pCur=pCur->next;
  768.  }
  769.  else
  770.  {//The same word as previous,delete it.
  771.  pTemp=pCur;
  772.       if(pPre!=NULL)//pCur is the first item
  773.  pPre->next=pCur->next;
  774.  else
  775.  m_pModifyTable[i].pWordItemHead=pCur->next;
  776.  pCur=pCur->next;
  777.  /* 
  778.  * ----- commented by huangjin@ict.ac.cn 2006-5-29 ------ 
  779.  * 
  780.  *  delete pTemp->data.sWord;//Delete the word
  781.  *
  782.  */  
  783.  /*----Added By huangjin@ict.ac.cn 2006-5-29----*/
  784.  delete []pTemp->data.sWord;//Delete the word
  785.  pTemp->data.sWord=NULL;
  786.  /*---------------------------------------------*/
  787.  delete pTemp;//Delete the item
  788.  }
  789.  }
  790.    }
  791. return true;
  792. }
  793. /*********************************************************************
  794.  *
  795.  *  Func Name  : GetMaxMatch
  796.  *
  797.  *  Description: Get the max match to the word
  798.  *              
  799.  *
  800.  *  Parameters : nHandle: the only handle which will be attached to the word
  801.  *  Returns    : success or fail
  802.  *  Author     : Kevin Zhang  
  803.  *  History    : 
  804.  *              1.create 2002-1-21
  805.  *********************************************************************/
  806. bool CDictionary::GetMaxMatch(char *sWord, char *sWordRet,int *npHandleRet)
  807. {
  808. /* 
  809. * ----- commented by huangjin@ict.ac.cn 2006-6-1 ------ 
  810. *
  811. *  char sWordGet[WORD_MAXLENGTH-2],sFirstChar[3];
  812. *
  813. */
  814. /*----Added By huangjin@ict.ac.cn 2006-6-1----*/
  815. char sWordGet[WORD_MAXLENGTH-2]="",sFirstChar[3]="";
  816. /*---------------------------------------------*/
  817. int nPos,nFoundPos,nTemp;
  818. PWORD_CHAIN pCur;
  819. *npHandleRet=-1;
  820. if(!PreProcessing(sWord, &nPos,sWordGet))
  821. return false;
  822. sWordRet[0]=0;
  823.    /* 
  824. * ----- commented by huangjin@ict.ac.cn 2006-5-31 ------ 
  825. *
  826. *  strncpy(sFirstChar,sWord,strlen(sWord)-strlen(sWordGet));//Get the first char
  827. * sFirstChar[strlen(sWord)-strlen(sWordGet)]=0;//Set the end flag
  828. *
  829. */
  830. /*----Added By huangjin@ict.ac.cn 2006-5-31----*/
  831. if(strlen(sWord)>strlen(sWordGet))
  832. {
  833. strncpy(sFirstChar,sWord,strlen(sWord)-strlen(sWordGet));//Get the first char
  834. sFirstChar[strlen(sWord)-strlen(sWordGet)]=0;//Set the end flag
  835. }
  836. /*---------------------------------------------*/
  837.    
  838. /* 
  839. * ----- commented by huangjin@ict.ac.cn 2006-9-17 ------ 
  840. *
  841. * FindInOriginalTable(nPos,sWordGet,-1,&nFoundPos);
  842. *
  843. */
  844. /*----Added By huangjin@ict.ac.cn 2006-9-17----*/
  845. if(!FindInOriginalTable(nPos,sWordGet,-1,&nFoundPos))
  846. return false;
  847. /*---------------------------------------------*/
  848.    
  849.    nTemp=nFoundPos;//Check its previous position
  850.    if(nFoundPos==-1)
  851. nTemp=0;
  852.    while(nTemp<m_IndexTable[nPos].nCount&&CC_Find(m_IndexTable[nPos].pWordItemHead[nTemp].sWord,sWordGet)!=m_IndexTable[nPos].pWordItemHead[nTemp].sWord)
  853.    {//Get the next
  854.    nTemp+=1;
  855.    }
  856.    if(nTemp<m_IndexTable[nPos].nCount&&CC_Find(m_IndexTable[nPos].pWordItemHead[nTemp].sWord,sWordGet)==m_IndexTable[nPos].pWordItemHead[nTemp].sWord)
  857.    {
  858.    strcpy(sWordRet,sFirstChar);
  859.    strcat(sWordRet,m_IndexTable[nPos].pWordItemHead[nTemp].sWord);
  860.    *npHandleRet=m_IndexTable[nPos].pWordItemHead[nTemp].nHandle;
  861.    return true;
  862.    }//Cannot get the item and retrieve the modified data if exists
  863.     //Operation in the index table and its items 
  864.    if(m_pModifyTable&&m_pModifyTable[nPos].pWordItemHead)//Exists 
  865.    pCur=m_pModifyTable[nPos].pWordItemHead;
  866.    else
  867.    pCur=NULL;
  868.    while(pCur!=NULL&&strcmp(pCur->data.sWord,sWordGet)<=0&&CC_Find(pCur->data.sWord,sWordGet)!=pCur->data.sWord)//
  869.    {
  870.    pCur=pCur->next;
  871.    }
  872.    /* 
  873. * ----- commented by huangjin@ict.ac.cn 2006-9-17 ------ 
  874. *
  875. * if(pCur!=NULL&&CC_Find(pCur->data.sWord,sWordGet)!=pCur->data.sWord)
  876. *
  877. */
  878. /*----Added By huangjin@ict.ac.cn 2006-9-17----*/
  879. if(pCur!=NULL&&CC_Find(pCur->data.sWord,sWordGet)==pCur->data.sWord)
  880. /*---------------------------------------------*/   
  881.    {//Get it
  882.    strcpy(sWordRet,sFirstChar);
  883.    strcat(sWordRet,pCur->data.sWord);
  884.    *npHandleRet=pCur->data.nHandle;
  885.    return true;
  886.    }
  887.    return false;
  888. }
  889. /*********************************************************************
  890.  *
  891.  *  Func Name  : GetPOSValue
  892.  *
  893.  *  Description: Get the POS value according the POS string
  894.  *              
  895.  *
  896.  *  Parameters : 
  897.  *  Returns    : the value
  898.  *  Author     : Kevin Zhang  
  899.  *  History    : 
  900.  *              1.create 2002-1-29
  901.  *********************************************************************/
  902. int CDictionary::GetPOSValue(char *sPOS)
  903. {
  904. int nPOS;
  905. char *sPlusPos,sTemp[4];
  906. if(strlen(sPOS)<3)
  907. {
  908. nPOS=sPOS[0]*256+sPOS[1];
  909. }
  910. else
  911. {
  912. sPlusPos=strchr(sPOS,'+');
  913. strncpy(sTemp,sPOS,sPlusPos-sPOS);
  914. sTemp[sPlusPos-sPOS]=0;
  915.         nPOS=100*GetPOSValue(sTemp);
  916. strncpy(sTemp,sPlusPos+1,4);
  917.         nPOS+=atoi(sTemp);
  918. }
  919. return nPOS;
  920. }
  921. /*********************************************************************
  922.  *
  923.  *  Func Name  : GetPOSString
  924.  *
  925.  *  Description: Get the POS string according the POS value
  926.  *              
  927.  *
  928.  *  Parameters : 
  929.  *  Returns    : success or fail
  930.  *  Author     : Kevin Zhang  
  931.  *  History    : 
  932.  *              1.create 2002-1-29
  933.  *********************************************************************/
  934. bool CDictionary::GetPOSString(int nPOS, char *sPOSRet)
  935. {
  936.     if(nPOS>'a'*25600) 
  937. {
  938. if((nPOS/100)%256!=0)
  939.   sprintf(sPOSRet,"%c%c+%d",nPOS/25600,(nPOS/100)%256,nPOS%100);
  940. else
  941. sprintf(sPOSRet,"%c+%d",nPOS/25600,nPOS%100);
  942. }
  943. else
  944. {
  945.   if(nPOS>256)
  946. sprintf(sPOSRet,"%c%c",nPOS/256,nPOS%256);
  947.   else
  948. sprintf(sPOSRet,"%c",nPOS%256);
  949. }
  950. return true;
  951. }
  952. int CDictionary::GetFrequency(char *sWord, int nHandle)
  953. {
  954.    char sWordFind[WORD_MAXLENGTH-2];
  955.    int nPos,nIndex;
  956.    PWORD_CHAIN pFound;
  957.    if(!PreProcessing(sWord, &nPos,sWordFind))
  958.    return 0;
  959.    if(FindInOriginalTable(nPos,sWordFind,nHandle,&nIndex))
  960.    {
  961. return m_IndexTable[nPos].pWordItemHead[nIndex].nFrequency;
  962.    }
  963.    if(FindInModifyTable(nPos,sWordFind,nHandle,&pFound))
  964.    {
  965.    return pFound->data.nFrequency;
  966.    }
  967.    return 0;
  968. }
  969. bool CDictionary::Output(char *sFilename)
  970. {
  971.    FILE *fp;
  972.    int i,j;
  973.    PWORD_CHAIN pCur;
  974.    char sPrevWord[WORD_MAXLENGTH]="", sCurWord[WORD_MAXLENGTH],sPOS[10];
  975.    if((fp=fopen(sFilename,"wb"))==NULL)
  976.    return false;//fail while opening the file
  977.    if(m_pModifyTable)
  978.    {//Modification made, not to output when modify table exists.
  979.    return false;
  980.    }   
  981.    for(i=0;i<CC_NUM;i++)
  982.    {
  983.    pCur=NULL;
  984.        j=0;  
  985.    while(j<m_IndexTable[i].nCount)
  986.    {
  987.  GetPOSString(m_IndexTable[i].pWordItemHead[j].nHandle,sPOS);
  988.  //Get the POS string
  989.  sprintf(sCurWord,"%c%c%s",CC_CHAR1(i),CC_CHAR2(i),m_IndexTable[i].pWordItemHead[j].sWord);
  990.          if(strcmp(sPrevWord,sCurWord)!=0)
  991.  fprintf(fp,"n%s %s",sCurWord,sPOS);
  992.  else
  993.  fprintf(fp," %s",sPOS);
  994.  strcpy(sPrevWord,sCurWord);
  995.    j+=1;//Get next item in the original table.
  996.    }
  997.    }
  998.    fclose(fp);
  999.    return true;
  1000. }
  1001. bool CDictionary::OutputChars(char *sFilename)
  1002. {
  1003.    FILE *fp;
  1004.    int i,j;
  1005.    char sPrevWord[WORD_MAXLENGTH]="", sCurWord[WORD_MAXLENGTH];
  1006.    if((fp=fopen(sFilename,"wb"))==NULL)
  1007.    return false;//fail while opening the file
  1008.    if(m_pModifyTable)
  1009.    {//Modification made, not to output when modify table exists.
  1010.    return false;
  1011.    }   
  1012.    for(i=0;i<CC_NUM;i++)
  1013.    {
  1014.        j=0;  
  1015.    while(j<m_IndexTable[i].nCount)
  1016.    {
  1017.  sprintf(sCurWord,"%c%c%s",CC_CHAR1(i),CC_CHAR2(i),m_IndexTable[i].pWordItemHead[j].sWord);
  1018.          if(strcmp(sPrevWord,sCurWord)!=0&&m_IndexTable[i].pWordItemHead[j].nFrequency>50)//
  1019.  fprintf(fp,"%s",sCurWord);
  1020.  strcpy(sPrevWord,sCurWord);
  1021.    j+=1;//Get next item in the original table.
  1022.    }
  1023.    }
  1024.    fclose(fp);
  1025.    return true;
  1026. }
  1027. bool CDictionary::Merge(CDictionary dict2, int nRatio)
  1028. //Merge dict2 into current dictionary and the frequency ratio from dict2 and current dict is nRatio
  1029. {
  1030.    int i,j,k,nCmpValue;
  1031.    char sWord[WORD_MAXLENGTH];
  1032.    if(m_pModifyTable||dict2.m_pModifyTable)
  1033.    {//Modification made, not to output when modify table exists.
  1034.    return false;
  1035.    }   
  1036.    for(i=0;i<CC_NUM;i++)
  1037.    {
  1038.        j=0; 
  1039.    k=0; 
  1040.    while(j<m_IndexTable[i].nCount&&k<dict2.m_IndexTable[i].nCount)
  1041.    {
  1042.  nCmpValue=strcmp(m_IndexTable[i].pWordItemHead[j].sWord,dict2.m_IndexTable[i].pWordItemHead[k].sWord);
  1043.  if(nCmpValue==0)//Same Words and determine the different handle
  1044.  {
  1045.  if(m_IndexTable[i].pWordItemHead[j].nHandle<dict2.m_IndexTable[i].pWordItemHead[k].nHandle)
  1046. nCmpValue=-1;
  1047.  else if(m_IndexTable[i].pWordItemHead[j].nHandle>dict2.m_IndexTable[i].pWordItemHead[k].nHandle)
  1048. nCmpValue=1;
  1049.  }
  1050.  if(nCmpValue==0)
  1051.  {
  1052.  m_IndexTable[i].pWordItemHead[j].nFrequency=(nRatio*m_IndexTable[i].pWordItemHead[j].nFrequency+dict2.m_IndexTable[i].pWordItemHead[k].nFrequency)/(nRatio+1);
  1053.  j+=1;
  1054.  k+=1;
  1055.  }
  1056.  else if(nCmpValue<0)//Get next word in the current dictionary
  1057.  {
  1058.  m_IndexTable[i].pWordItemHead[j].nFrequency=(nRatio*m_IndexTable[i].pWordItemHead[j].nFrequency)/(nRatio+1);
  1059.  j+=1;
  1060.  }
  1061.  else//Get next word in the second dictionary
  1062.  {
  1063.   if(dict2.m_IndexTable[i].pWordItemHead[k].nFrequency>(nRatio+1)/10)
  1064.   {
  1065.   sprintf(sWord,"%c%c%s",CC_CHAR1(i),CC_CHAR2(i),dict2.m_IndexTable[i].pWordItemHead[k].sWord);
  1066.   AddItem(sWord,dict2.m_IndexTable[i].pWordItemHead[k].nHandle,dict2.m_IndexTable[i].pWordItemHead[k].nFrequency/(nRatio+1));
  1067.   }
  1068.  k+=1;
  1069.  }
  1070.    }
  1071.    while(j<m_IndexTable[i].nCount)//words in current dictionary are left
  1072.    {
  1073.  m_IndexTable[i].pWordItemHead[j].nFrequency=(nRatio*m_IndexTable[i].pWordItemHead[j].nFrequency)/(nRatio+1);
  1074.  j+=1;
  1075.    }
  1076.    while(k<dict2.m_IndexTable[i].nCount)//words in Dict2 are left
  1077.    {
  1078. if(dict2.m_IndexTable[i].pWordItemHead[k].nFrequency>(nRatio+1)/10)
  1079. {
  1080.  sprintf(sWord,"%c%c%s",CC_CHAR1(i),CC_CHAR2(i),dict2.m_IndexTable[i].pWordItemHead[k].sWord);
  1081.  AddItem(sWord,dict2.m_IndexTable[i].pWordItemHead[k].nHandle,dict2.m_IndexTable[i].pWordItemHead[k].nFrequency/(nRatio+1));
  1082. }
  1083.         k+=1;
  1084.    }
  1085.    }
  1086.    return true;
  1087. }
  1088. //Delete word item which 
  1089. //(1)frequency is 0 
  1090. //(2)word is same as following but the POS value is parent set of the following
  1091. //for example "江泽民/n/0" will deleted, because "江泽民/nr/0" is more detail and correct
  1092. bool CDictionary::Optimum()
  1093. {
  1094.    int nPrevPOS,i,j,nPrevFreq;
  1095.    char sPrevWord[WORD_MAXLENGTH],sCurWord[WORD_MAXLENGTH];
  1096.    for(i=0;i<CC_NUM;i++)
  1097.    {
  1098.        j=0;  
  1099.    sPrevWord[0]=0;
  1100.    nPrevPOS=0;
  1101.    nPrevFreq=-1;
  1102.    while(j<m_IndexTable[i].nCount)
  1103.    {
  1104.  sprintf(sCurWord,"%c%c%s",CC_CHAR1(i),CC_CHAR2(i),m_IndexTable[i].pWordItemHead[j].sWord);
  1105.          if(nPrevPOS==30720||nPrevPOS==26368||nPrevPOS==29031||(strcmp(sPrevWord,sCurWord)==0&&nPrevFreq==0&&m_IndexTable[i].pWordItemHead[j].nHandle/256*256==nPrevPOS))
  1106.  {//Delete Previous word item
  1107.   //Delete word with POS 'x','g' 'qg'
  1108. DelItem(sPrevWord,nPrevPOS);
  1109.  }
  1110.  strcpy(sPrevWord,sCurWord);
  1111.  nPrevPOS=m_IndexTable[i].pWordItemHead[j].nHandle;
  1112.  nPrevFreq=m_IndexTable[i].pWordItemHead[j].nFrequency;
  1113.    j+=1;//Get next item in the original table.
  1114.    }
  1115.    }
  1116.    return true;
  1117. }
  1118. /*----Added By huangjin@ict.ac.cn 2006-5-29----*/
  1119. void CDictionary::ClearDictionary()
  1120. {
  1121. /*----Added By huangjin@ict.ac.cn 2006-9-12----*/
  1122.    if(!m_bAvailable)
  1123.    return; //needn't to clear.
  1124.    /*---------------------------------------------*/
  1125. for(int i=0;i<CC_NUM;i++)
  1126. {//delete the memory of word item array in the dictionary
  1127. for(int j=0;j<m_IndexTable[i].nCount;j++)
  1128. {
  1129. delete []m_IndexTable[i].pWordItemHead[j].sWord;
  1130. m_IndexTable[i].pWordItemHead[j].sWord=NULL;
  1131. }
  1132. delete [] m_IndexTable[i].pWordItemHead;
  1133. m_IndexTable[i].pWordItemHead=NULL;
  1134. m_IndexTable[i].nCount=0;
  1135. }
  1136.     DelModified();
  1137. /*----Added By huangjin@ict.ac.cn 2006-9-12----*/
  1138. m_bAvailable=false;
  1139.    /*---------------------------------------------*/
  1140. }
  1141. /*-----------------------------------------------*/