搜索引擎技術在碼農眼里一直是比較高大上,其中文分詞是中文自然語言處理領域的基礎研究,也是中文搜索引擎的核心模塊之一,現在我們來用C語言簡單實現一下中文搜索引擎中文分詞.
目前而言的分詞系統絕大多數都是基于中文詞典的匹配算法,其中,最為常見的是最大匹配算法(Maximum Matching,以下簡稱MM算法),而MM算法有三種:一種正向最大匹配、一種逆向最大匹配和雙向匹配,本文以正向最大匹配算法為例介紹其基本思想和實現.
一、基本思想
(1)假設詞典中最長的詞語字數為w(一般設置為8個字符,即4個漢字).
(2)判斷帶分詞語句長度是否大于w個字,如果大于w則跳到(3),如果小于w則跳到(6).
(3)取待分詞語句的前w個字。
(4)在詞典中查找w,如果存在,則從語句中去掉w,從語句中w后的詞開始重復上面過程.
(5)如果不存在,就去掉這w個字的最后一個字.
(6)檢查是否是單字或者空,如果是,則退出.
(7)如果不是,則繼續判斷詞庫中是否存在這個詞,如此反復循環,直到輸出一個詞.
(8)繼續取短語的前w個字反復循環,這樣就可以將一個語句分成詞語的組合了.
二、簡單實現,代碼如下:
- #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個字節)
- #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);
- //繼續匹配
- 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()
- {
- //構造詞庫
- 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: %sn", (*itor).c_str());
- } //Vevb.com
- return 0;
- }
新聞熱點
疑難解答