搜尋引擎的那些事(中文分詞)

來源:互聯網
上載者:User

【 聲明:著作權,歡迎轉載,請勿用於商業用途。  聯絡信箱:feixiaoxing @163.com】 

    前面,我們在介紹搜尋引擎的時候也談到過中文分詞。和英文不一樣,中文上所有的漢字都是連在一起的,所以我們的一項工作就是把這些詞語拆分成一個一個片語。因為只有這樣才能構建索引資料庫、才能尋找索引,我們構建搜尋引擎的工作才能繼續進行下去。

    現在關於中分分詞有好多的分詞方法,什麼從左向右最大長度法、從右向左最大長度法、最少片語法、貝葉斯機率處理法等等。但是說了這麼多,我們分詞的標準是什麼,關鍵還在於有一個好的分詞字典。中國漢字那麼多,但是數量上估計幾萬個足夠了。但是如果漢字與漢字組合起來構成片語,那數量就多了去了,比如說文學詞語、口語、人名、地名、詩詞、專業術語等等。說到這裡,可以給大家舉個例子看一下。大家都喜歡搜狗IME,一方面它的設計比較人性化,另外一方面不正是因為它詞庫很多、使用方便嗎?

    關於分詞的演算法,有的人覺得很玄乎,其實寫一個也不複雜,我們就可以寫一個最大長度遍曆的分詞演算法。當然這裡只是考慮了漢字分詞,如果是英文、數字、繁體字或者符號,那就要另外考慮了。這也驗證了我們之前反覆說的一句話,簡單做一件事不難,關鍵是怎麼做好了、幹漂亮了、高效又能節省成本。

 

#include <stdio.h>#include <string.h>#include <memory.h>#include <malloc.h>#define LENGTH 256static char* dic[] = {"北京", "大學", "北京大學"};#define NUMBER (sizeof(dic) / sizeof(char*))static char* buffer[LENGTH] = {0};static int max_len = 0;static int min_len = 0;static int  find_max_length(){int index;unsigned int len;len = 0;for(index = 0; index < NUMBER; index ++){if(len < strlen(dic[index])){len = strlen(dic[index]);}}return len;}static int find_min_length(){int index;unsigned int len;len = strlen(dic[0]);for(index = 1; index < NUMBER; index++){if(strlen(dic[index]) < len){len = strlen(dic[index]);}}return len;}static void show_buffer(int end){int start;for(start = 0; start < end; start ++){printf("%s ", buffer[start]);}printf("\n");}static void _process_segment(char* str, int index){int start;int len ;int  found;char* data;char* label;if('\0' == *str){        show_buffer(index);return;}label = str + strlen(str);retry:len = strlen(str);if(len > LENGTH){len = LENGTH;}if(len > max_len){len = max_len;}found = 0;while(len >= min_len){for(start = 0; start < NUMBER; start ++){if(0 == strncmp(str, dic[start], len)){found = 1;break;}}if(found){break;}len --;}/* if no str was found, just step forward, but cannot beyond label */if(len < min_len && str < label){str ++;goto retry;}/* if no str was left, show all the str */if(str >= label){show_buffer(index);return;}data = (char*) malloc(len + 1);if(NULL == data){return;}data[len] = '\0';memmove(data, str, len);buffer[index] = data;_process_segment(str + len, index + 1);free(data);buffer[index] = NULL;}void process_segment(char* str){int length;if(NULL == str){return;}length = strlen(str);if(length > LENGTH){return;}_process_segment(str, 0);}void segment_init(){min_len = find_min_length();max_len = find_max_length();memset(buffer, 0,  sizeof(buffer));}int main(int argc, char* argv[]){segment_init();process_segment("北京 大學 日本");return 1;}  

 

    代碼中最複雜的函數其實就是_segment_process這個函數,中間涉及的情況比較多,可以簡單介紹一下:

    (1)分詞的時候建議考慮一下當前詞庫的最小長度和最大長度,可以避免不必要的比較;

    (2)分詞如果尋找失敗,跳過從下一個位元組開始繼續尋找;

    (3)函數採用了遞迴的方法,注意函數出口;

    (4)函數編寫的時候注意buffer堆棧的浮動處理;

    (5)注意函數中判斷條件的依據和原因。

    (6)這裡dic的詞庫數量太少,要想利用process_segment進行分詞處理,詞庫數量必須足夠多。

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.