中文分詞一直都是中文自然語言處理領(lǐng)域的基礎(chǔ)研究,也是中文搜索引擎的核心模塊之一。目前而言的分詞系統(tǒng)絕大多數(shù)都是基于中文詞典的匹配算法,其中,最為常見的是最大匹配算法 (Maximum Matching,以下簡稱MM算法) ,而MM算法有三種:一種正向最大匹配、一種逆向最大匹配和雙向匹配。本文以正向最大匹配算法為例介紹其基本思想和實現(xiàn)。
一、基本思想
(1)假設(shè)詞典中最長的詞語字?jǐn)?shù)為w(一般設(shè)置為8個字符,即4個漢字)。
(2)判斷帶分詞語句長度是否大于w個字,如果大于w則跳到(3),如果小于w則跳到(6)。
(3)取待分詞語句的前w個字。
(4)在詞典中查找w,如果存在,則從語句中去掉w,從語句中w后的詞開始重復(fù)上面過程。
(5)如果不存在,就去掉這w個字的最后一個字。
(6)檢查是否是單字或者空,如果是,則退出。
(7)如果不是,則繼續(xù)判斷詞庫中是否存在這個詞,如此反復(fù)循環(huán),直到輸出一個詞。
(8)繼續(xù)取短語的前w個字反復(fù)循環(huán),這樣就可以將一個語句分成詞語的組合了。
二、簡單實現(xiàn)
#include <stdio.h>
#include <string>
#include <set>
using namespace std;
set<string> g_setWordDictionary;
int construct()
{
g_setWordDictionary.insert("中國");
g_setWordDictionary.insert("中國人");
g_setWordDictionary.insert("紐約");
g_setWordDictionary.insert("北京");
}
bool match(string &word)
{
set<string>::iterator itor = g_setWordDictionary.find(word);
if (itor == g_setWordDictionary.end())
{
return false;
}
return true;
}
void forward_maximum_matching(string content, set<string> &keywords)
{
#define MAX_LEN 12 //詞庫中最長詞語(utf-8一個漢字3個字節(jié))
#define MIN_LEN 3 //單字(原理同上)
int len = content.length();
int right_len = len;
int start_pos = 0;
bool ret = false;
string kw_value = "";
int kw_len = 0;
int kw_pos = 0;
//單字或空串
while (right_len > MIN_LEN)
{
//語句大于詞庫中最長詞語
if (right_len >= MAX_LEN)
{
kw_value = content.substr(start_pos, MAX_LEN);
}
//語句小于詞庫中最長詞語
else
{
kw_value = content.substr(start_pos, right_len);
}
//詞庫匹配
ret = match(kw_value);
kw_len = kw_value.length();
kw_pos = 0;
while (!ret && kw_len > 2*MIN_LEN)
{
//去掉候選詞右邊一個漢字
kw_len -= MIN_LEN;
kw_value = kw_value.substr(kw_pos, kw_len);
//繼續(xù)匹配
ret = match(kw_value);
}
//匹配到詞
if (ret)
{
keywords.insert(kw_value);
//從語句中去掉匹配到的詞
start_pos += kw_len;
right_len = len - start_pos;
}
//未匹配到詞,下移一個字
else
{
start_pos += MIN_LEN;
right_len = len - start_pos;
}
}//while (right_len > MIN_LEN)
}
int main()
{
//構(gòu)造詞庫
construct();
//切分詞庫
string content = "我是中國人,我是來自中國北京的中國人,在紐約工作";
set<string> keywords;
forward_maximum_matching(content, keywords);
set<string>::iterator itor;
//輸出分詞
for (itor=keywords.begin(); itor!=keywords.end(); ++itor)
{
printf("result: %s\n", (*itor).c_str());
}
return 0;
}
原文://blog.chinaunix.net/uid-22312037-id-4442837.html
標(biāo)簽:
搜索控件
本站文章除注明轉(zhuǎn)載外,均為本站原創(chuàng)或翻譯。歡迎任何形式的轉(zhuǎn)載,但請務(wù)必注明出處、不得修改原文相關(guān)鏈接,如果存在內(nèi)容上的異議請郵件反饋至chenjj@fc6vip.cn
文章轉(zhuǎn)載自:慧都控件網(wǎng)