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

多国语言处理

开发平台:

C/C++

  1. /****************************************************************************
  2.  *
  3.  * Copyright (c) 2000, 2001 
  4.  *     Machine Group
  5.  *     Software Research Lab.
  6.  *     Institute of Computing Tech.
  7.  *     Chinese Academy of Sciences
  8.  *     All rights reserved.
  9.  *
  10.  * This file is the confidential and proprietary property of 
  11.  * Institute of Computing Tech. and the posession or use of this file requires 
  12.  * a written license from the author.
  13.  * Filename: Dictionary.cpp
  14.  * Abstract:
  15.  *           implementation of the CDictionary class.
  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 "Dictionary.h"
  25. #include "Utility.h"
  26. #include <string.h>
  27. #include <stdlib.h>
  28. #include <malloc.h>
  29. #include <stdio.h>
  30. //////////////////////////////////////////////////////////////////////
  31. // Construction/Destruction
  32. //////////////////////////////////////////////////////////////////////
  33. CDictionary::CDictionary()
  34. {
  35.   //initilization
  36.   memset(m_IndexTable,0,sizeof(m_IndexTable));
  37.   m_pModifyTable=NULL;
  38. }
  39. CDictionary::~CDictionary()
  40. {
  41. for(int i=0;i<CC_NUM;i++)
  42. {//delete the memory of word item array in the dictionary
  43. for(int j=0;j<m_IndexTable[i].nCount;j++)
  44. delete m_IndexTable[i].pWordItemHead[j].sWord;
  45. delete [] m_IndexTable[i].pWordItemHead;
  46. }
  47.     DelModified();
  48. }
  49. /*********************************************************************
  50.  *
  51.  *  Func Name  : Load
  52.  *
  53.  *  Description: Load the dictionary from the file .dct
  54.  *              
  55.  *
  56.  *  Parameters : sFilename: the file name
  57.  *
  58.  *  Returns    : success or fail
  59.  *  Author     : Kevin Zhang  
  60.  *  History    : 
  61.  *              1.create 2002-1-9
  62.  *********************************************************************/
  63. bool CDictionary::Load(char *sFilename,bool bReset)
  64. {
  65.    FILE *fp;
  66.    int i,j,nBuffer[3];
  67.    if((fp=fopen(sFilename,"rb"))==NULL)
  68.    return false;//fail while opening the file
  69.    
  70.    //Release the memory for new files
  71.    for( i=0;i<CC_NUM;i++)
  72. {//delete the memory of word item array in the dictionary
  73. for( j=0;j<m_IndexTable[i].nCount;j++)
  74. delete m_IndexTable[i].pWordItemHead[j].sWord;
  75. delete [] m_IndexTable[i].pWordItemHead;
  76. }
  77.     DelModified();
  78.    for(i=0;i<CC_NUM;i++)
  79.    {
  80.    fread(&(m_IndexTable[i].nCount),sizeof(int),1,fp);
  81.        if(m_IndexTable[i].nCount>0)
  82.      m_IndexTable[i].pWordItemHead=new WORD_ITEM[m_IndexTable[i].nCount];
  83.    else 
  84.    {
  85.    m_IndexTable[i].pWordItemHead=0;
  86.    continue;
  87.    }
  88.        j=0;
  89.    while(j<m_IndexTable[i].nCount)
  90.    {
  91.          fread(nBuffer,sizeof(int),3,fp);
  92.          m_IndexTable[i].pWordItemHead[j].sWord=new char[nBuffer[1]+1];
  93.     if(nBuffer[1])//String length is more than 0
  94.  {
  95.  fread(m_IndexTable[i].pWordItemHead[j].sWord,sizeof(char),nBuffer[1],fp);
  96.  }
  97.  m_IndexTable[i].pWordItemHead[j].sWord[nBuffer[1]]=0;
  98.         if(bReset)//Reset the frequency
  99.           m_IndexTable[i].pWordItemHead[j].nFrequency=0;
  100.  else
  101.               m_IndexTable[i].pWordItemHead[j].nFrequency=nBuffer[0];
  102.  m_IndexTable[i].pWordItemHead[j].nWordLen=nBuffer[1];
  103.  m_IndexTable[i].pWordItemHead[j].nHandle=nBuffer[2];
  104.    j+=1;//Get next item in the original table.
  105.    }
  106.    }
  107.    fclose(fp);
  108.    return true;
  109. }
  110. /*********************************************************************
  111.  *
  112.  *  Func Name  : Save
  113.  *
  114.  *  Description: Save the dictionary as the file .dct
  115.  *              
  116.  *
  117.  *  Parameters : sFilename: the file name
  118.  *
  119.  *  Returns    : success or fail
  120.  *  Author     : Kevin Zhang  
  121.  *  History    : 
  122.  *              1.create 2002-1-9
  123.  *********************************************************************/
  124. bool CDictionary::Save(char *sFilename)
  125. {
  126.    FILE *fp;
  127.    int i,j,nCount,nBuffer[3];
  128.    PWORD_CHAIN pCur;
  129.    if((fp=fopen(sFilename,"wb"))==NULL)
  130.    return false;//fail while opening the file
  131.    for(i=0;i<CC_NUM;i++)
  132.    {
  133.    pCur=NULL;
  134.    if(m_pModifyTable)
  135.    {//Modification made
  136.    nCount=m_IndexTable[i].nCount+m_pModifyTable[i].nCount-m_pModifyTable[i].nDelete;
  137.    fwrite(&nCount,sizeof(int),1,fp);
  138.    pCur=m_pModifyTable[i].pWordItemHead;
  139.    j=0;
  140.    while(pCur!=NULL&&j<m_IndexTable[i].nCount)
  141.    {//Output to the file after comparision
  142.    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))
  143.    {//Output the modified data to the file
  144.  nBuffer[0]=pCur->data.nFrequency;
  145.          nBuffer[1]=pCur->data.nWordLen;
  146.      nBuffer[2]=pCur->data.nHandle;
  147.                  fwrite(nBuffer,sizeof(int),3,fp);
  148.  if(nBuffer[1])//String length is more than 0
  149.           fwrite(pCur->data.sWord,sizeof(char),nBuffer[1],fp);
  150.                  pCur=pCur->next;//Get next item in the modify table.
  151.    }
  152.    else if(m_IndexTable[i].pWordItemHead[j].nFrequency==-1)
  153.    {//The item has been removed,so skip it
  154.    j+=1;
  155.    }
  156.    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))
  157.    {//Output the index table data to the file
  158.  nBuffer[0]=m_IndexTable[i].pWordItemHead[j].nFrequency;
  159.  nBuffer[1]=m_IndexTable[i].pWordItemHead[j].nWordLen;
  160.  nBuffer[2]=m_IndexTable[i].pWordItemHead[j].nHandle;
  161.  fwrite(nBuffer,sizeof(int),3,fp);
  162.  if(nBuffer[1])//String length is more than 0
  163.    fwrite(m_IndexTable[i].pWordItemHead[j].sWord,sizeof(char),nBuffer[1],fp);
  164.  j+=1;//Get next item in the original table.
  165.    }
  166.    }
  167.    if(j<m_IndexTable[i].nCount)
  168.    {
  169.    while(j<m_IndexTable[i].nCount)
  170.    {
  171.    if(m_IndexTable[i].pWordItemHead[j].nFrequency!=-1)
  172.    {//Has been deleted
  173.  nBuffer[0]=m_IndexTable[i].pWordItemHead[j].nFrequency;
  174.  nBuffer[1]=m_IndexTable[i].pWordItemHead[j].nWordLen;
  175.  nBuffer[2]=m_IndexTable[i].pWordItemHead[j].nHandle;
  176.  fwrite(nBuffer,sizeof(int),3,fp);
  177.  if(nBuffer[1])//String length is more than 0
  178.    fwrite(m_IndexTable[i].pWordItemHead[j].sWord,sizeof(char),nBuffer[1],fp);
  179.    }
  180.    j+=1;//Get next item in the original table.
  181.    }
  182.    }
  183.    else////No Modification
  184.    while(pCur!=NULL)//Add the rest data to the file.
  185.    {
  186.  nBuffer[0]=pCur->data.nFrequency;
  187.          nBuffer[1]=pCur->data.nWordLen;
  188.      nBuffer[2]=pCur->data.nHandle;
  189.                  fwrite(nBuffer,sizeof(int),3,fp);
  190.  if(nBuffer[1])//String length is more than 0
  191.    fwrite(pCur->data.sWord,sizeof(char),nBuffer[1],fp);
  192.                  pCur=pCur->next;//Get next item in the modify table.
  193.    }
  194.    }
  195.    else
  196.    {
  197.    fwrite(&m_IndexTable[i].nCount,sizeof(int),1,fp);
  198.    //write to the file
  199.            j=0;  
  200.    while(j<m_IndexTable[i].nCount)
  201.    {
  202.  nBuffer[0]=m_IndexTable[i].pWordItemHead[j].nFrequency;
  203.      nBuffer[1]=m_IndexTable[i].pWordItemHead[j].nWordLen;
  204.  nBuffer[2]=m_IndexTable[i].pWordItemHead[j].nHandle;
  205.              fwrite(nBuffer,sizeof(int),3,fp);
  206.  if(nBuffer[1])//String length is more than 0
  207.    fwrite(m_IndexTable[i].pWordItemHead[j].sWord,sizeof(char),nBuffer[1],fp);
  208.    j+=1;//Get next item in the original table.
  209.    }
  210.    }
  211.    }
  212.    fclose(fp);
  213.    return true;
  214. }
  215. /*********************************************************************
  216.  *
  217.  *  Func Name  : AddItem
  218.  *
  219.  *  Description: Add a word item to the dictionary
  220.  *              
  221.  *
  222.  *  Parameters : sWord: the word
  223.  *               nHandle:the handle number
  224.  *               nFrequency: the frequency
  225.  *  Returns    : success or fail
  226.  *  Author     : Kevin Zhang  
  227.  *  History    : 
  228.  *              1.create 2002-1-9
  229.  *********************************************************************/
  230. bool CDictionary::AddItem(char *sWord, int nHandle,int nFrequency)
  231. {
  232.    char sWordAdd[WORD_MAXLENGTH-2];
  233.    int nPos,nFoundPos;
  234.    PWORD_CHAIN pRet,pTemp,pNext;
  235.    int i=0;
  236.    if(!PreProcessing(sWord, &nPos,sWordAdd,true))
  237.    return false;
  238.    if(FindInOriginalTable(nPos,sWordAdd,nHandle,&nFoundPos))
  239.    {//The word exists in the original table, so add the frequency
  240.     //Operation in the index table and its items 
  241.        if(m_IndexTable[nPos].pWordItemHead[nFoundPos].nFrequency==-1)
  242.    {//The word item has been removed
  243.       m_IndexTable[nPos].pWordItemHead[nFoundPos].nFrequency=nFrequency;
  244.         if(!m_pModifyTable)//Not prepare the buffer
  245.   {
  246.    m_pModifyTable=new MODIFY_TABLE[CC_NUM];
  247.    memset(m_pModifyTable,0,CC_NUM*sizeof(MODIFY_TABLE));
  248.   }
  249.   m_pModifyTable[nPos].nDelete-=1;
  250.    }
  251.    else
  252.   m_IndexTable[nPos].pWordItemHead[nFoundPos].nFrequency+=nFrequency;
  253.    return true;
  254.    }
  255.    //The items not exists in the index table.
  256.    //As following, we have to find the item whether exists in the modify data region
  257.    //If exists, change the frequency .or else add a item
  258.    if(!m_pModifyTable)//Not prepare the buffer
  259.    {
  260.    m_pModifyTable=new MODIFY_TABLE[CC_NUM];
  261.    memset(m_pModifyTable,0,CC_NUM*sizeof(MODIFY_TABLE));
  262.    }
  263.    if(FindInModifyTable(nPos,sWordAdd,nHandle,&pRet))
  264.    {
  265.    if(pRet!=NULL)
  266.    pRet=pRet->next;
  267.    else
  268.    pRet=m_pModifyTable[nPos].pWordItemHead;
  269.    pRet->data.nFrequency+=nFrequency;
  270.    return true;
  271.    }
  272.    //find the proper position to add the word to the modify data table and link
  273.    pTemp=new WORD_CHAIN;//Allocate the word chain node
  274.    if(pTemp==NULL)//Allocate memory failure
  275.    return false;
  276.    memset(pTemp,0,sizeof(WORD_CHAIN));//init it with 0
  277.    pTemp->data.nHandle=nHandle;//store the handle 
  278.    pTemp->data.nWordLen=strlen(sWordAdd);
  279.    pTemp->data.sWord=new char[1+pTemp->data.nWordLen];
  280.    strcpy(pTemp->data.sWord,sWordAdd);
  281.    pTemp->data.nFrequency=nFrequency;
  282.    pTemp->next=NULL;   
  283.    if(pRet!=NULL)
  284.    {
  285.    pNext=pRet->next;//Get the next item before the current item
  286.    pRet->next=pTemp;//link the node to the chain
  287.    }
  288.    else
  289.    {
  290.    pNext=m_pModifyTable[nPos].pWordItemHead;
  291.    m_pModifyTable[nPos].pWordItemHead=pTemp;//Set the pAdd as the head node
  292.    }
  293.    pTemp->next=pNext;//Very important!!!! or else it will lose some node
  294.    //Modify in 2001-10-29
  295.    m_pModifyTable[nPos].nCount++;//the number increase by one
  296.    return true;
  297. }
  298. bool CDictionary::DelItem(char *sWord,int nHandle)
  299. {
  300.    char sWordDel[WORD_MAXLENGTH-2];
  301.    int nPos,nFoundPos,nTemp;
  302.    PWORD_CHAIN pPre,pTemp,pCur;
  303.    if(!PreProcessing(sWord, &nPos,sWordDel))
  304.    return false;
  305.    if(FindInOriginalTable(nPos,sWordDel,nHandle,&nFoundPos))
  306.    {
  307.        if(!m_pModifyTable)//Not prepare the buffer
  308.    {
  309.    m_pModifyTable=new MODIFY_TABLE[CC_NUM];
  310.    memset(m_pModifyTable,0,CC_NUM*sizeof(MODIFY_TABLE));
  311.    }
  312.        m_IndexTable[nPos].pWordItemHead[nFoundPos].nFrequency=-1;
  313.    m_pModifyTable[nPos].nDelete+=1;
  314.    if(nHandle==-1)//Remove all items which word is sWordDel,ignoring the handle
  315.    {
  316. /*    nTemp=nFoundPos-1;//Check its previous position
  317.    while(nTemp>0&&strcmp(m_IndexTable[nPos].pWordItemHead[nFoundPos].sWord,sWordDel)==0)
  318.    {
  319. m_IndexTable[nPos].pWordItemHead[nTemp].nFrequency=-1;
  320. m_pModifyTable[nPos].nDelete+=1;
  321. nTemp-=1;
  322.    }
  323. */    nTemp=nFoundPos+1;//Check its previous position
  324.    while(nTemp<m_IndexTable[nPos].nCount&&strcmp(m_IndexTable[nPos].pWordItemHead[nFoundPos].sWord,sWordDel)==0)
  325.    {
  326. m_IndexTable[nPos].pWordItemHead[nTemp].nFrequency=-1;
  327. m_pModifyTable[nPos].nDelete+=1;
  328. nTemp+=1;
  329.    }
  330.    }
  331.    return true;
  332.    }
  333.    //Operation in the modify table and its items 
  334.    if(FindInModifyTable(nPos,sWordDel,nHandle,&pPre))
  335.    {
  336.      pCur=m_pModifyTable[nPos].pWordItemHead;
  337.      if(pPre!=NULL)
  338.  pCur=pPre->next;
  339.          while(pCur!=NULL && _stricmp(pCur->data.sWord,sWordDel)==0&&(pCur->data.nHandle==nHandle||nHandle<0))
  340.  {
  341.  pTemp=pCur;
  342.       if(pPre!=NULL)//pCur is the first item
  343.  pPre->next=pCur->next;
  344.  else
  345.  m_pModifyTable[nPos].pWordItemHead=pCur->next;
  346.  pCur=pCur->next;
  347.  delete pTemp->data.sWord;//Delete the word
  348.  delete pTemp;
  349.  }
  350.    return true;
  351.    }
  352.    return false;
  353. }
  354. bool CDictionary::DelModified()
  355. {
  356.   PWORD_CHAIN pTemp,pCur;
  357.   if(!m_pModifyTable)
  358.   return true;
  359.   for(int i=0;i<CC_NUM;i++)
  360.   {
  361.       pCur=m_pModifyTable[i].pWordItemHead;
  362.   while(pCur!=NULL)
  363.   {
  364.   pTemp=pCur;
  365.   pCur=pCur->next;
  366.   delete pTemp->data.sWord;
  367.   delete pTemp;
  368.   }
  369.   }
  370.   delete [] m_pModifyTable;
  371.   m_pModifyTable=NULL;
  372.   return true;
  373. }
  374. bool CDictionary::IsExist(char *sWord,  int nHandle)
  375. {
  376.    char sWordFind[WORD_MAXLENGTH-2];
  377.    int nPos;
  378.    if(!PreProcessing(sWord, &nPos,sWordFind))
  379.    return false;
  380.    return(FindInOriginalTable(nPos,sWordFind,nHandle)||FindInModifyTable(nPos,sWordFind,nHandle));
  381. }
  382. bool CDictionary::GetHandle(char *sWord,int *pnCount,int *pnHandle,int *pnFrequency)
  383. {
  384.    char sWordGet[WORD_MAXLENGTH-2];
  385.    int nPos,nFoundPos,nTemp;
  386.    PWORD_CHAIN pPre,pCur;
  387.    *pnCount=0;
  388.    if(!PreProcessing(sWord, &nPos,sWordGet))
  389.    return false;
  390.    if(FindInOriginalTable(nPos,sWordGet,-1,&nFoundPos))
  391.    {
  392.        pnHandle[*pnCount]=m_IndexTable[nPos].pWordItemHead[nFoundPos].nHandle;
  393.    pnFrequency[*pnCount]=m_IndexTable[nPos].pWordItemHead[nFoundPos].nFrequency;
  394.    *pnCount+=1;
  395. /*    nTemp=nFoundPos-1;//Check its previous position
  396.    while(nTemp>0&&strcmp(m_IndexTable[nPos].pWordItemHead[nTemp].sWord,sWordGet)==0)
  397.    {
  398.    pnHandle[*pnCount]=m_IndexTable[nPos].pWordItemHead[nTemp].nHandle;
  399.    pnFrequency[*pnCount]=m_IndexTable[nPos].pWordItemHead[nTemp].nFrequency;
  400.    *pnCount+=1;
  401.        nTemp-=1;
  402.    }
  403. */    nTemp=nFoundPos+1;//Check its previous position
  404.    while(nTemp<m_IndexTable[nPos].nCount&&strcmp(m_IndexTable[nPos].pWordItemHead[nTemp].sWord,sWordGet)==0)
  405.    {
  406.    pnHandle[*pnCount]=m_IndexTable[nPos].pWordItemHead[nTemp].nHandle;
  407.    pnFrequency[*pnCount]=m_IndexTable[nPos].pWordItemHead[nTemp].nFrequency;
  408.    *pnCount+=1;
  409.    nTemp+=1;
  410.    }
  411.    return true;
  412.    }
  413.    //Operation in the index table and its items 
  414.    if(FindInModifyTable(nPos,sWordGet,-1,&pPre))
  415.    {
  416.      pCur=m_pModifyTable[nPos].pWordItemHead;
  417.      if(pPre!=NULL)
  418.  pCur=pPre->next;
  419.          while(pCur!=NULL && _stricmp(pCur->data.sWord,sWordGet)==0)
  420.  {
  421.  pnHandle[*pnCount]=pCur->data.nHandle;
  422.  pnFrequency[*pnCount]=pCur->data.nFrequency;
  423.  *pnCount+=1;
  424.    pCur=pCur->next;
  425.  }
  426.    return true;
  427.    }
  428.    return false;
  429. }
  430. /*********************************************************************
  431.  *
  432.  *  Func Name  : FindInOriginalTable
  433.  *
  434.  *  Description: judge the word and handle exist in the inner table and its items
  435.  *              
  436.  *
  437.  *  Parameters : nInnerCode: the inner code of the first CHines char
  438.  *               sWord: the word
  439.  *               nHandle:the handle number
  440.  *               *nPosRet:the position which node is matched
  441.  *
  442.  *  Returns    : success or fail
  443.  *  Author     : Kevin Zhang  
  444.  *  History    : 
  445.  *              1.create 2002-1-9
  446.  *********************************************************************/
  447. bool CDictionary::FindInOriginalTable(int nInnerCode,char *sWord,int nHandle,int *nPosRet)
  448. {
  449.     PWORD_ITEM pItems=m_IndexTable[nInnerCode].pWordItemHead;
  450. int nStart=0,nEnd=m_IndexTable[nInnerCode].nCount-1,nMid=(nStart+nEnd)/2,nCount=0,nCmpValue;
  451. while(nStart<=nEnd)//Binary search
  452. {
  453.        nCmpValue=strcmp(pItems[nMid].sWord,sWord);
  454.        if(nCmpValue==0&&(pItems[nMid].nHandle==nHandle||nHandle==-1))
  455.    {
  456.    if(nPosRet)
  457.    {
  458.    if(nHandle==-1)//Not very strict match
  459.    {//Add in 2002-1-28
  460.    nMid-=1;
  461.    while(nMid>=0&&strcmp(pItems[nMid].sWord,sWord)==0)
  462.    //Get the first item which match the current word
  463.    nMid--;
  464.                    if(nMid<0||strcmp(pItems[nMid].sWord,sWord)!=0)
  465.    nMid++;
  466.    }
  467.    *nPosRet=nMid;
  468.                return true;   
  469.    }
  470.         if(nPosRet)
  471. *nPosRet=nMid;
  472. return true;//find it
  473.    }
  474.    else if(nCmpValue<0||(nCmpValue==0&&pItems[nMid].nHandle<nHandle&&nHandle!=-1))
  475.    {
  476.    nStart=nMid+1;
  477.    }
  478.    else if(nCmpValue>0||(nCmpValue==0&&pItems[nMid].nHandle>nHandle&&nHandle!=-1))
  479.        {
  480.    nEnd=nMid-1;
  481.    }
  482.    nMid=(nStart+nEnd)/2;
  483. }
  484.     if(nPosRet)
  485. {
  486. //Get the previous position
  487. *nPosRet=nMid-1;
  488. }
  489. return false;
  490. }
  491. /*********************************************************************
  492.  *
  493.  *  Func Name  : FindInModifyTable
  494.  *
  495.  *  Description: judge the word and handle exist in the modified table and its items
  496.  *              
  497.  *
  498.  *  Parameters : nInnerCode: the inner code of the first CHines char
  499.  *               sWord: the word
  500.  *               nHandle:the handle number
  501.  *               *pFindRet: the node found
  502.  *
  503.  *  Returns    : success or fail
  504.  *  Author     : Kevin Zhang  
  505.  *  History    : 
  506.  *              1.create 2002-1-9
  507.  *********************************************************************/
  508. bool CDictionary::FindInModifyTable(int nInnerCode,char *sWord,int nHandle,PWORD_CHAIN *pFindRet)
  509. {
  510.    PWORD_CHAIN pCur,pPre;
  511.    if(m_pModifyTable==NULL)//empty
  512.    return false;
  513.    pCur=m_pModifyTable[nInnerCode].pWordItemHead;
  514.    pPre=NULL;
  515.    while(pCur!=NULL&&(_stricmp(pCur->data.sWord,sWord)<0||(_stricmp(pCur->data.sWord,sWord)==0&&pCur->data.nHandle<nHandle)))
  516.    //sort the link chain as alphabet
  517.    {
  518.        pPre=pCur;
  519.    pCur=pCur->next;
  520.    }
  521.    if(pFindRet)
  522.      *pFindRet=pPre;
  523.    if(pCur!=NULL && _stricmp(pCur->data.sWord,sWord)==0&&(pCur->data.nHandle==nHandle||nHandle<0))
  524.    {//The node exists, delete the node and return 
  525.    return true;
  526.    }
  527.    return false;
  528. }
  529. /*********************************************************************
  530.  *
  531.  *  Func Name  : GetWordType
  532.  *
  533.  *  Description: Get the type of word
  534.  *              
  535.  *
  536.  *  Parameters : sWord: the word
  537.  *  Returns    : the type
  538.  *  Author     : Kevin Zhang  
  539.  *  History    : 
  540.  *              1.create 2002-1-9
  541.  *********************************************************************/
  542. int CDictionary::GetWordType(char *sWord)
  543. {
  544.    int nType=charType((unsigned char *)sWord),nLen=strlen(sWord);
  545.    if(nLen>0&&nType==CT_CHINESE&&IsAllChinese((unsigned char *)sWord))
  546.    return WT_CHINESE;//Chinese word
  547.    else if(nLen>0&&nType==CT_DELIMITER)
  548.        return WT_DELIMITER;//Delimiter
  549.    else
  550.    return WT_OTHER;//other invalid
  551. }
  552. /*********************************************************************
  553.  *
  554.  *  Func Name  : PreProcessing
  555.  *
  556.  *  Description: Get the type of word
  557.  *              
  558.  *
  559.  *  Parameters : sWord: the word
  560.  *  Returns    : the type
  561.  *  Author     : Kevin Zhang  
  562.  *  History    : 
  563.  *              1.create 2002-1-9
  564.  *********************************************************************/
  565. bool CDictionary::PreProcessing(char *sWord, int *nId, char *sWordRet,bool bAdd)
  566. {
  567.    //Position for the delimeters
  568.    int nType=charType((unsigned char *)sWord),nLen=strlen(sWord);
  569.    int nEnd=nLen-1,nBegin=0;
  570.    if(nLen==0)
  571.    return false;
  572.    while(nEnd>=0&&sWord[nEnd]==' ')
  573. nEnd-=1;
  574.    while(nBegin<=nEnd&&sWord[nBegin]==' ')
  575. nBegin+=1;
  576.    if(nBegin>nEnd)
  577.    return false;
  578.    if(nEnd!=nLen-1||nBegin!=0)
  579.    {
  580.    strncpy(sWord,sWord+nBegin,nEnd-nBegin+1);
  581.    sWord[nEnd-nBegin+1]=0;
  582.    }
  583. /*
  584.    if((bAdd||strlen(sWord)>4)&&IsAllChineseNum(sWord))
  585.    {  //Only convert the Chinese Num to 3755 while 
  586.       //Get the inner code of the first Chinese Char
  587.        strcpy(sWord,"五十八");
  588.    }
  589. */   
  590.    if(nType==CT_CHINESE)//&&IsAllChinese((unsigned char *)sWord)
  591.    {//Chinese word
  592.    *nId=CC_ID(sWord[0],sWord[1]);
  593.    //Get the inner code of the first Chinese Char
  594. strcpy(sWordRet,&sWord[2]);//store the word,not store the first Chinese Char
  595. return true;
  596.    }
  597. /* if(nType==CT_NUM&&IsAllNum((unsigned char *)sWord))
  598.    {
  599.    *nId=3756;
  600.        //Get the inner code of the first Chinese Char
  601.        sWordRet[0]=0;//store the word,not store the first Chinese Char
  602.    return true;
  603.    }
  604. */ if(nType==CT_DELIMITER)
  605.    {//Delimiter
  606.    *nId=3755;
  607.        //Get the inner code of the first Chinese Char
  608.        strcpy(sWordRet,sWord);//store the word,not store the first Chinese Char
  609.    return true;
  610.    }
  611. /*
  612.    if(nType==CT_LETTER&&IsAllLetter((unsigned char *)sWord))
  613.    {
  614.    *nId=3757;
  615.        //Get the inner code of the first Chinese Char
  616.        sWordRet[0]=0;//store the word,not store the first Chinese Char
  617.    return true;
  618.    }
  619.    if(nType==CT_SINGLE&&IsAllSingleByte((unsigned char *)sWord))
  620.    {
  621.    *nId=3758;
  622.        //Get the inner code of the first Chinese Char
  623.        sWordRet[0]=0;//store the word,not store the first Chinese Char
  624.    return true;
  625.    }
  626.    if(nType==CT_INDEX&&IsAllIndex((unsigned char *)sWord))
  627.    {
  628.    *nId=3759;
  629.        //Get the inner code of the first Chinese Char
  630.        sWordRet[0]=0;//store the word,not store the first Chinese Char
  631.    return true;
  632.    }
  633. */
  634.    return false;//other invalid
  635. }
  636. /*********************************************************************
  637.  *
  638.  *  Func Name  : MergePOS
  639.  *
  640.  *  Description: Merge all the POS into nHandle,
  641.  *              just get the word in the dictionary and set its Handle as nHandle
  642.  *              
  643.  *
  644.  *  Parameters : nHandle: the only handle which will be attached to the word
  645.  *  Returns    : the type
  646.  *  Author     : Kevin Zhang  
  647.  *  History    : 
  648.  *              1.create 2002-1-21
  649.  *********************************************************************/
  650. bool CDictionary::MergePOS(int nHandle)
  651. {
  652.     int i,j,nCompare;
  653. char sWordPrev[WORD_MAXLENGTH];
  654. PWORD_CHAIN pPre,pCur,pTemp;
  655.     if(!m_pModifyTable)//Not prepare the buffer
  656.     {
  657.    m_pModifyTable=new MODIFY_TABLE[CC_NUM];
  658.    memset(m_pModifyTable,0,CC_NUM*sizeof(MODIFY_TABLE));
  659.     }
  660. for( i=0;i<CC_NUM;i++)//Operation in the index table
  661. {//delete the memory of word item array in the dictionary
  662. sWordPrev[0]=0;//Set empty
  663. for(j=0;j<m_IndexTable[i].nCount;j++)
  664. {
  665. nCompare=_stricmp(sWordPrev,m_IndexTable[i].pWordItemHead[j].sWord);
  666.             if((j==0||nCompare<0)&&m_IndexTable[i].pWordItemHead[j].nFrequency!=-1)
  667. {//Need to modify its handle
  668.     m_IndexTable[i].pWordItemHead[j].nHandle=nHandle;//Change its handle
  669. strcpy(sWordPrev,m_IndexTable[i].pWordItemHead[j].sWord);//Refresh previous Word
  670. }
  671. else if(nCompare==0&&m_IndexTable[i].pWordItemHead[j].nFrequency!=-1)
  672. {//Need to delete when not delete and same as previous word
  673. m_IndexTable[i].pWordItemHead[j].nFrequency=-1;//Set delete flag
  674. m_pModifyTable[i].nDelete+=1;//Add the number of being deleted
  675. }
  676. }
  677. }
  678. for( i=0;i<CC_NUM;i++)//Operation in the modify table
  679. {
  680.  pPre=NULL;
  681.      pCur=m_pModifyTable[i].pWordItemHead;
  682.  sWordPrev[0]=0;//Set empty
  683.          while(pCur!=NULL)
  684.  {
  685.  if(_stricmp(pCur->data.sWord,sWordPrev)>0)
  686.  {//The new word
  687. pCur->data.nHandle=nHandle;//Chang its handle
  688. strcpy(sWordPrev,pCur->data.sWord);//Set new previous word
  689. pPre=pCur;//New previous pointer
  690. pCur=pCur->next;
  691.  }
  692.  else
  693.  {//The same word as previous,delete it.
  694.  pTemp=pCur;
  695.       if(pPre!=NULL)//pCur is the first item
  696.  pPre->next=pCur->next;
  697.  else
  698.  m_pModifyTable[i].pWordItemHead=pCur->next;
  699.  pCur=pCur->next;
  700.    delete pTemp->data.sWord;//Delete the word
  701.  delete pTemp;//Delete the item
  702.  }
  703.  }
  704.    }
  705. return true;
  706. }
  707. /*********************************************************************
  708.  *
  709.  *  Func Name  : GetMaxMatch
  710.  *
  711.  *  Description: Get the max match to the word
  712.  *              
  713.  *
  714.  *  Parameters : nHandle: the only handle which will be attached to the word
  715.  *  Returns    : success or fail
  716.  *  Author     : Kevin Zhang  
  717.  *  History    : 
  718.  *              1.create 2002-1-21
  719.  *********************************************************************/
  720. bool CDictionary::GetMaxMatch(char *sWord, char *sWordRet,int *npHandleRet)
  721. {
  722.    char sWordGet[WORD_MAXLENGTH-2],sFirstChar[3];
  723.    int nPos,nFoundPos,nTemp;
  724.    PWORD_CHAIN pCur;
  725.    *npHandleRet=-1;
  726.    if(!PreProcessing(sWord, &nPos,sWordGet))
  727.    return false;
  728.    sWordRet[0]=0;
  729.    strncpy(sFirstChar,sWord,strlen(sWord)-strlen(sWordGet));//Get the first char
  730.    sFirstChar[strlen(sWord)-strlen(sWordGet)]=0;//Set the end flag
  731.    FindInOriginalTable(nPos,sWordGet,-1,&nFoundPos);
  732.    nTemp=nFoundPos;//Check its previous position
  733.    if(nFoundPos==-1)
  734. nTemp=0;
  735.    while(nTemp<m_IndexTable[nPos].nCount&&CC_Find(m_IndexTable[nPos].pWordItemHead[nTemp].sWord,sWordGet)!=m_IndexTable[nPos].pWordItemHead[nTemp].sWord)
  736.    {//Get the next
  737.    nTemp+=1;
  738.    }
  739.    if(nTemp<m_IndexTable[nPos].nCount&&CC_Find(m_IndexTable[nPos].pWordItemHead[nTemp].sWord,sWordGet)==m_IndexTable[nPos].pWordItemHead[nTemp].sWord)
  740.    {
  741.    strcpy(sWordRet,sFirstChar);
  742.    strcat(sWordRet,m_IndexTable[nPos].pWordItemHead[nTemp].sWord);
  743.    *npHandleRet=m_IndexTable[nPos].pWordItemHead[nTemp].nHandle;
  744.    return true;
  745.    }//Cannot get the item and retrieve the modified data if exists
  746.     //Operation in the index table and its items 
  747.    if(m_pModifyTable&&m_pModifyTable[nPos].pWordItemHead)//Exists 
  748.    pCur=m_pModifyTable[nPos].pWordItemHead;
  749.    else
  750.    pCur=NULL;
  751.    while(pCur!=NULL&&strcmp(pCur->data.sWord,sWordGet)<=0&&CC_Find(pCur->data.sWord,sWordGet)!=pCur->data.sWord)//
  752.    {
  753.    pCur=pCur->next;
  754.    }
  755.    if(pCur!=NULL&&CC_Find(pCur->data.sWord,sWordGet)!=pCur->data.sWord)
  756.    {//Get it
  757.    strcpy(sWordRet,sFirstChar);
  758.    strcat(sWordRet,pCur->data.sWord);
  759.    *npHandleRet=pCur->data.nHandle;
  760.    return true;
  761.    }
  762.    return false;
  763. }
  764. /*********************************************************************
  765.  *
  766.  *  Func Name  : GetPOSValue
  767.  *
  768.  *  Description: Get the POS value according the POS string
  769.  *              
  770.  *
  771.  *  Parameters : 
  772.  *  Returns    : the value
  773.  *  Author     : Kevin Zhang  
  774.  *  History    : 
  775.  *              1.create 2002-1-29
  776.  *********************************************************************/
  777. int CDictionary::GetPOSValue(char *sPOS)
  778. {
  779. int nPOS;
  780. char *sPlusPos,sTemp[4];
  781. if(strlen(sPOS)<3)
  782. {
  783. nPOS=sPOS[0]*256+sPOS[1];
  784. }
  785. else
  786. {
  787. sPlusPos=strchr(sPOS,'+');
  788. strncpy(sTemp,sPOS,sPlusPos-sPOS);
  789. sTemp[sPlusPos-sPOS]=0;
  790.         nPOS=100*GetPOSValue(sTemp);
  791. strncpy(sTemp,sPlusPos+1,4);
  792.         nPOS+=atoi(sTemp);
  793. }
  794. return nPOS;
  795. }
  796. /*********************************************************************
  797.  *
  798.  *  Func Name  : GetPOSString
  799.  *
  800.  *  Description: Get the POS string according the POS value
  801.  *              
  802.  *
  803.  *  Parameters : 
  804.  *  Returns    : success or fail
  805.  *  Author     : Kevin Zhang  
  806.  *  History    : 
  807.  *              1.create 2002-1-29
  808.  *********************************************************************/
  809. bool CDictionary::GetPOSString(int nPOS, char *sPOSRet)
  810. {
  811.     if(nPOS>'a'*25600) 
  812. {
  813. if((nPOS/100)%256!=0)
  814.   sprintf(sPOSRet,"%c%c+%d",nPOS/25600,(nPOS/100)%256,nPOS%100);
  815. else
  816. sprintf(sPOSRet,"%c+%d",nPOS/25600,nPOS%100);
  817. }
  818. else
  819. {
  820.   if(nPOS>256)
  821. sprintf(sPOSRet,"%c%c",nPOS/256,nPOS%256);
  822.   else
  823. sprintf(sPOSRet,"%c",nPOS%256);
  824. }
  825. return true;
  826. }
  827. int CDictionary::GetFrequency(char *sWord, int nHandle)
  828. {
  829.    char sWordFind[WORD_MAXLENGTH-2];
  830.    int nPos,nIndex;
  831.    PWORD_CHAIN pFound;
  832.    if(!PreProcessing(sWord, &nPos,sWordFind))
  833.    return 0;
  834.    if(FindInOriginalTable(nPos,sWordFind,nHandle,&nIndex))
  835.    {
  836. return m_IndexTable[nPos].pWordItemHead[nIndex].nFrequency;
  837.    }
  838.    if(FindInModifyTable(nPos,sWordFind,nHandle,&pFound))
  839.    {
  840.    return pFound->data.nFrequency;
  841.    }
  842.    return 0;
  843. }
  844. bool CDictionary::Output(char *sFilename)
  845. {
  846.    FILE *fp;
  847.    int i,j;
  848.    PWORD_CHAIN pCur;
  849.    char sPrevWord[WORD_MAXLENGTH]="", sCurWord[WORD_MAXLENGTH],sPOS[10];
  850.    if((fp=fopen(sFilename,"wb"))==NULL)
  851.    return false;//fail while opening the file
  852.    if(m_pModifyTable)
  853.    {//Modification made, not to output when modify table exists.
  854.    return false;
  855.    }   
  856.    for(i=0;i<CC_NUM;i++)
  857.    {
  858.    pCur=NULL;
  859.        j=0;  
  860.    while(j<m_IndexTable[i].nCount)
  861.    {
  862.  GetPOSString(m_IndexTable[i].pWordItemHead[j].nHandle,sPOS);
  863.  //Get the POS string
  864.  sprintf(sCurWord,"%c%c%s",CC_CHAR1(i),CC_CHAR2(i),m_IndexTable[i].pWordItemHead[j].sWord);
  865.          if(strcmp(sPrevWord,sCurWord)!=0)
  866.  fprintf(fp,"n%s %s",sCurWord,sPOS);
  867.  else
  868.  fprintf(fp," %s",sPOS);
  869.  strcpy(sPrevWord,sCurWord);
  870.    j+=1;//Get next item in the original table.
  871.    }
  872.    }
  873.    fclose(fp);
  874.    return true;
  875. }