中文分詞中的正向最大匹配與逆向最大匹配

2021-08-27 22:05:53 字數 4412 閱讀 5883

我們都知道,英文的分詞由於單詞間是以空格進行分隔的,所以分詞要相對的容易些,而中文就不同了,中文中乙個句子的分隔就是以字為單位的了,而所謂的正向最大匹配和逆向最大匹配便是一種分詞匹配的方法,這裡以詞典匹配說明。

所謂詞典正向最大匹配就是將一段字串進行分隔,其中分隔 的長度有限制,然後將分隔的子字串與字典中的詞進行匹配,如果匹配成功則進行下一輪匹配,直到所有字串處理完畢,否則將子字串從末尾去除乙個字,再進行匹配,如此反覆。逆向匹配與此類似,下面以乙個例子來說明:

要進行分詞的字串:「研究生命的起源」

研究

研究生

生命

起源

假定最大匹配字數設定為5

正向最大匹配過程:

研究生命的

研究生命

研究生#第乙個詞匹配成功

命的起源

命的起命的

#第二個詞匹配成功,乙個單字

的起源的起

#第三個詞匹配成功

起源 #第四個詞匹配成功

那麼正向最大匹配的結果就是

研究生 命 的 起源

現在我們來看看逆向最大匹配的過程:

生命的起源

命的起源

的起源起源 #第乙個詞匹配成功

研究生命的

究生命的

生命的命的

的 #第二個詞匹配成功

研究生命

究生命生命#第三個詞匹配成功

研究#第四個詞匹配成功

所以逆向最大匹配後的結果為

研究 生命 的 起源

兩種分詞過程總結:

【正向匹配:從左到右,逐步去掉右部(底部)的字進行新一輪匹配,逆向匹配:從右到左,逐步去掉左部(底部)的字進行新一輪匹配】

因為中文比較複雜以及中文的特殊性,逆向最大匹配大多時候往往會比正向要準確。

從上面可以看出來,其實進行匹配並不困難,當然首先我們得找到乙個好的詞典。比如漢語詞典,搜狗詞典等,然後將其載入進乙個雜湊表裡,最後從輸入讀取字串進行匹配,做中文分詞這個還是使用指令碼語言比較好,比如python,c 語言做這個比較坑,特別是對字串的分隔要掌握好,而且非常麻煩,下面所處理的中文是utf-8編碼的,所以如果你輸入的字串不是utf-8編碼可能該程式會無法工作。

#include #include #include #define hash_len 39841 //定義雜湊表大小

#define stack_len 100 //定義棧大小

#define max 5 //最大匹配字數

typedef struct hash_node

hash_node; //雜湊表下拉鍊表結果

typedef struct

hash; //雜湊表資料結構

typedef struct

stack; //棧資料結構

//雜湊函式,計算雜湊值

unsigned int hash_fun(char *key)

return hash&0x7fffffff;

}//初始化雜湊表

void hash_init(hash *hash)

//衝突時拉下鍊錶

void hash_list_insert(hash_node *data,char *key)

//插入資料

void hash_insert(hash *hash,char *key)

//當前表中資料值加1

++hash[h].len;

}//從該錶位址中進行搜尋

char *hash_node_key(hash_node *node,char *key)

return null;

}//從雜湊表查詢

char *hash_get(hash *hash,char *key)

//判斷資料是否在該表中

int hash_node_in(hash_node *node,char *key)

return 0;

}//如若存在則返回1

//否則返回0

int hash_in(hash *hash,char *key)

//列印表的所有資料

void hash_list_print(hash_node *data)

}//列印雜湊表

void hash_print(hash *hash)

}}//載入詞典資料並存入雜湊表中

void load_data(hash *hash,char *path)

fclose(fp);

}//初始化棧

void stack_init(stack *stack)

//壓入乙個資料到棧中

int stack_push(stack *stack,char *data)

//從棧中彈出乙個資料

char *stack_pop(stack *stack)

//正向最大匹配

int for_match(hash *hash,stack *stack,char *data,int *index)

len-=3;

data=realloc(data,sizeof(char)*len+1);

data[len]='\0';

}return 0;

}//逆向最大匹配

int re_match(hash *hash,stack *stack,char *data,int *index)

data+=3;

len-=3;

}return 0;

}//預處理字串

void pre_set(char *str)

; int i=0;

int index=0;

while(i < strlen(str))

else if((str[i]&0xc0) == 0xc0) //標點等

i+=2;

else if((str[i]&0x80) == 0) //英文本元

++i;

}//重新設定字串

memset(str,0,strlen(str)+1);

snprintf(str,strlen(temp)+1,"%s",temp);

}int main(int argc,char **argv)

; //輸入的字串

int i=0;

int index=0;

char *temp; //取出的字串

//初始化

hash_init(hash);

stack_init(&stack);

stack_init(&res);

load_data(hash,"./現代漢語常用詞表.txt");

//hash_print(hash);

printf("請輸入乙個字串:");

//scanf("%s",string);

fgets(string,600,stdin);

//預處理字串,去除英文和其它非中文本元

pre_set(string);

//開始正向取出字串

while(i< strlen(string))

}//將匹配結果重新排序並列印

while(temp=stack_pop(&stack))

stack_push(&res,temp);

printf("正向最大匹配:\n");

while(temp=stack_pop(&res))

printf("%s ",temp);

//取出逆向匹配字串

printf("\n\n");

i=strlen(string);

while(i > 0)

//去除已匹配的字串

string[i]='\0';

}//列印匹配結果

printf("逆向最大匹配:\n");

while(temp=stack_pop(&stack))

printf("%s ",temp);

printf("\n");

return 0;

}

中文分詞 正向最大匹配與逆向最大匹配

正向 前向 最大匹配與逆向 後向 最大匹配。中文分詞目前可以分為 規則分詞 統計分詞 混合分詞 規則 統計 這三個主要流派。這次介紹下基於規則的分詞,其是一種機械的分詞方法,主要通過維護詞典,在切分語句時,將語句的每個字串與詞表中的詞逐一進行匹配,找到則切分,否則不予切分。正向最大匹配演算法 這裡需...

分詞演算法 正向最大匹配和逆向最大匹配實現

假設已經有正向匹配演算法原始碼,則可以將文件進行倒序處理,生成逆序文件,然後根據逆序詞典,對逆序文件使用正向最大匹配法處理即可。同理已經存在逆向最大匹配演算法,則只要將文件倒序處理,正向詞典倒序變為逆序詞典,則可以送入逆向西大匹配演算法中進行分詞處理。class imm object def ini...

中文分詞之正向最大匹配演算法

中文分詞目前可以分為 規則分詞 統計分詞 混合分詞 規則 統計 這三個主要流派。這次介紹下基於規則的分詞,其是一種機械的分詞方法,主要通過維護詞典,在切分語句時,將語句的每個字串與詞表中的詞逐一進行匹配,找到則切分,否則不予切分。正向最大匹配演算法 這裡需要知道兩點,乙個是分詞詞典 也即是已經分詞過...