我們都知道,英文的分詞由於單詞間是以空格進行分隔的,所以分詞要相對的容易些,而中文就不同了,中文中乙個句子的分隔就是以字為單位的了,而所謂的正向最大匹配和逆向最大匹配便是一種分詞匹配的方法,這裡以詞典匹配說明。
所謂詞典正向最大匹配就是將一段字串進行分隔,其中分隔 的長度有限制,然後將分隔的子字串與字典中的詞進行匹配,如果匹配成功則進行下一輪匹配,直到所有字串處理完畢,否則將子字串從末尾去除乙個字,再進行匹配,如此反覆。逆向匹配與此類似,下面以乙個例子來說明:
要進行分詞的字串:「研究生命的起源」
研究
研究生
生命
命
的
起源
假定最大匹配字數設定為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...
中文分詞之正向最大匹配演算法
中文分詞目前可以分為 規則分詞 統計分詞 混合分詞 規則 統計 這三個主要流派。這次介紹下基於規則的分詞,其是一種機械的分詞方法,主要通過維護詞典,在切分語句時,將語句的每個字串與詞表中的詞逐一進行匹配,找到則切分,否則不予切分。正向最大匹配演算法 這裡需要知道兩點,乙個是分詞詞典 也即是已經分詞過...