基于有序HASH树SDK应用---中文分词

来源:互联网 发布:云计算基础架构平台 编辑:程序博客网 时间:2024/06/06 08:27

有关有序HASHSDK请参考以下网址

http://topic.csdn.net/u/20090820/08/cd6917ee-b22e-412f-8bf1-9afd6770c7e8.html

1.1  基于词典中文分词介绍

这种方法又叫做机械分词方法,它是按照一定的策略将待分析的汉字串与一个充分大的机器词典中的词条进行匹配,若在词典中找到某个字符串,则匹配成功。按照扫描方向的不同,字符串匹配分词方法可以分为正向匹配和逆向匹配;按照不同长度优先匹配的情况,可以分为最大匹配和最小匹配。常用的两种分词方法如下:

 

1)正向最大匹配。

正向最大匹配法目的是将最长的词分离出来,例如从文本的开始位置在词典中匹配出最长的词,例如词典中有以下:中华、中华人民、中华人民共和国、华人、人民、共和、共和国、人民共和国、万岁。如果对以下文本进行分词:

“中华人民共和国万岁”,首先分出“中华人民共和国“这个词,而不是更短的”中华“、”中华人民“,然后解析出”万岁“这个词,依次类推解析出文本中的所有出现在词典中的词。

 

2)逆向最大匹配。

逆向最大匹配法的基本原理和正向最大匹配法相同,不同的是分词切分的方向与正向最大匹配法相反,并且使用的分词词典也不同。在实际处理时,先将文档进行倒排处理,生成逆序文档。然后,根据逆序词典,对逆序文档用正向最大匹配法处理即可。

 

3)最多匹配。

从文本中解析出所有的词,包括最长、最短以及其他所有出现在置在词典中词,例如词典中有以下:中华、中华人民、中华人民共和国、华人、人民、共和、共和国、人民共和国、万岁。如果对以下文本进行分词:

“中华人民共和国万岁”,可以解析出:中华、中华人民、中华人民共和国、华人、人民、共和、共和国、人民共和国、万岁。

 

基于有序HASH树可以开发出正向匹配分词、反向匹配分词;支持最大匹配、最小匹配、最多匹配。

 

1.2  功能实现原理

基于有序HASH树进行关键词的实现原理是把前缀匹配规则插入到有序HASH

中,然后使用SDK中的反向模糊匹配函数输入文本进行模糊匹配,即可返回满足

条件的前缀规则列表。

 

1、生成字典库

   把所有的词组插入到有序HASH树中,后期可以从字典库中增加、删除中文词

组。

 

2、最长(短)匹配

   从要分词的文本的开始位置在有序HASH树中调用相关函数进行反向模糊匹

配,如果匹配出一个最长(短)词组,则从文本的开始位置移动刚才词组的

长度,继续进行最长(短)匹配分词操作;如果没有匹配出结果,则从文本

的开始位置移动一个字符再进行最长(短)匹配分词操作。

 

3、最多匹配

   从要分词的文本的开始位置在有序HASH树中调用相关函数进行反向模糊匹

配,有可能匹配出一个或多个词组,也可能没有匹配出结果,然后从文本

的开始位置移动一个字符再进行最多匹配分词操作。

 

1.3  分词技术特点

1、支持超大规模字典词库

32位计算机系统,支持上百万的词组;对64位计算机系统,词组的数量

没有限制。

 

1、匹配速度快

基于有序HASH树的分词的速度与字典库的词组数量无关。

 

2、支持最长匹配、最短匹配、最多匹配等分词方式。

 

3、支持中英文混合分词

 

4、支持动态增加、删除字典库。

 

5、其它有序HASH树的强大功能

 

1.4  中文分词技术指标

1、分词速度

1)测试环境:

132windows xp操作系统

21G DDR2内存

3CPUAMD LE1100/1.9GHz

 

2)字典库

    中华

中华人民

中华人民共和国

华人

人民

共和

共和国

人民共和国

万岁

 。。。。。。。

    3)文本

中华人民共和国万岁

 

   4)最长匹配速度

      17万次/秒,即每秒处理170万个汉字的分词操作。

 

2、最大词组长度

255个字节

 

3、容量大

支持上百万字典库

 

1.5  正向最长匹配分词-源码实例1

示例:

功能:根据最长匹配方式对“中华人民共和国万岁”进行分词,解析出“中华人民共和国”、“万岁”

 

#include <stdio.h>

#include "HashTree.h"

 

bool FilterProc(LPSELECTCOND pCond)

{  

    char* sKey;

    sKey = (char *)(pCond->pFilterPara);

    HTreeGetCurrentKey(pCond, 0, sKey);

 

    int nLength;

    nLength = strlen(sKey);

 

    sKey[nLength-1] = '/0';

   

    fprintf(stdout, "%s/r/n", sKey);

   

    return true;

}  

 

int AccessSingle(HANDLE hTree, char* sText, char* sKeyWord)

{      

    SELECTCOND pSelectCond;

   

    pSelectCond.hTree = hTree; 

    pSelectCond.nMethod[0] = RTDB_METHOD_MATCH;

    pSelectCond.sIndexValue[0] = sText;

    pSelectCond.bEnableTop = true; 

    pSelectCond.nTopCount = 1; 

    pSelectCond.pFilterAPI = FilterProc;

    pSelectCond.pFilterPara = sKeyWord;

   

    HTreeSelect(&pSelectCond); 

   

    return 0;

}

 

int main(int nArgc, char* sArgv[])

{  

    MEMINITINFO MemInitInfo;

   

    MemInitInfo.nSysMaxIdleCount = 1000000;

    MemInitInfo.nAppMaxIdleCount = 1000000;

   

    int nRet;

    nRet = HTSysInit(&MemInitInfo);

    if(nRet != 0)

    {

        return nRet;

    }

   

    HANDLE hTree;  

    HTREEDESC TreeDesc;

    TreeDesc.nColumn = 1; 

    TreeDesc.nColDataType[0] = CACHE_STRING;       

    hTree = HTreeCreate(&TreeDesc);

   

    char* sPrefix[10];

    sPrefix[0] =  "中华%";

    sPrefix[1] =  "华人%";

    sPrefix[2] =  "中华人民%";

    sPrefix[3] =  "人民%";

    sPrefix[4] =  "共和%";

    sPrefix[5] =  "共和国%";

    sPrefix[6] =  "人民共和国%";

    sPrefix[7] =  "中华人民共和国%";

    sPrefix[8] =  "万岁%";

    sPrefix[9] =  "共和国万岁%";   

   

    int i;

    for (i = 0; i < 10; i++)

    {

        char* sMultiKey[32];

        sMultiKey[0] = sPrefix[i];     

        HTreeAddKey(hTree, sMultiKey, (void*)(i+1));

    }

   

    char* sText = "中华人民共和国万岁";

   

    while(sText[0] != '/0')

    {

        char sKeyWord[256];

        sKeyWord[0] = '/0';

        AccessSingle(hTree, sText, sKeyWord);

        if(strlen(sKeyWord) > 0)

        {

            sText += strlen(sKeyWord);

        }

        else

        {

            sText++;

        }

    }  

   

    HTSysDestroy();

   

    return 0;

}

 

1.6  正向最多匹配词-源码实例2

示例:

功能:根据最长匹配方式对“中华人民共和国万岁”进行分词,解析出:

中华华人中华人民人民  共和共和国

人民共和国中华人民共和国 万岁共和国万岁 

 

#include <stdio.h>

#include "HashTree.h"

 

bool FilterProc(LPSELECTCOND pCond)

{    

       char* sKey;

       sKey = (char *)(pCond->pFilterPara);

       HTreeGetCurrentKey(pCond, 0, sKey);

 

       int nLength;

       nLength = strlen(sKey);

 

       sKey[nLength-1] = '/0';

      

       fprintf(stdout, "%s/r/n", sKey);

 

       return true;

}    

 

int AccessSingle(HANDLE hTree, char* sText, char* sKeyWord)

{           

       SELECTCOND pSelectCond;

      

       pSelectCond.hTree = hTree; 

       pSelectCond.nMethod[0] = RTDB_METHOD_MATCH;

       pSelectCond.sIndexValue[0] = sText;   

       pSelectCond.bEnableTop = true;  

       pSelectCond.nTopCount = 1;

       pSelectCond.pFilterAPI = FilterProc;

       pSelectCond.pFilterPara = sKeyWord; 

      

       HTreeSelect(&pSelectCond);

      

       return 0;

}

 

int main(int nArgc, char* sArgv[])

{    

       MEMINITINFO MemInitInfo;

      

       MemInitInfo.nSysMaxIdleCount = 1000000;

       MemInitInfo.nAppMaxIdleCount = 1000000;

      

       int nRet;

       nRet = HTSysInit(&MemInitInfo);

       if(nRet != 0)

       {

              return nRet;

       }

      

       HANDLE hTree;   

       HTREEDESC TreeDesc;

       TreeDesc.nColumn = 1; 

       TreeDesc.nColDataType[0] = CACHE_STRING;       

       hTree = HTreeCreate(&TreeDesc);

      

       char* sPrefix[10];

       sPrefix[0] =  "中华%";

       sPrefix[1] =  "华人%";

       sPrefix[2] =  "中华人民%";

       sPrefix[3] =  "人民%";

       sPrefix[4] =  "共和%";

       sPrefix[5] =  "共和国%";

       sPrefix[6] =  "人民共和国%";

       sPrefix[7] =  "中华人民共和国%";

       sPrefix[8] =  "万岁%";

       sPrefix[9] =  "共和国万岁%";   

      

       int i;

       for (i = 0; i < 10; i++)

       {

              char* sMultiKey[32];

              sMultiKey[0] = sPrefix[i];           

              HTreeAddKey(hTree, sMultiKey, (void*)(i+1));

       }           

 

       char* sText = "中华人民共和国万岁";      

       while(sText[0] != '/0')

       {

              char sKeyWord[256];

              sKeyWord[0] = '/0';

              AccessSingle(hTree, sText, sKeyWord);            

              sText++;       

       }

 

       HTSysDestroy();

      

    return 0;

}

 

 

 

原创粉丝点击