编写简单的中文分词程序 几个月之前,在网上找到了一个中文词库素材(几百K),当时便想写一个分词程序了.我对汉语分词没有什么研究,也就凭自己臆想而写.若有相关方面专家,还请多给意见. 一、词库 词库大概有5万多词语(google能搜到,类似的词库都能用),我摘要如下: 地区 82 重要 81 新华社 80 技术 80 会议 80 自己 79 干部 78 职工 78 群众 77 没有 77 今天 76 同志 76 部门 75 加强 75 组织 75 第一列是词,第二列是权重.我写的这个分词算法目前并未利用权重. 二、设计思路 算法简要描述: 对一个字符串S,从前到后扫描,对扫描的每个字,从词库中寻找最长匹配.比如假设S="我是中华人民共和国公民",词库中有"中华人民共和国","中华","公民","人民","共和国"......等词.当扫描到"中"字,那么从中字开始,向后分别取1,2,3,......个字("中","中华","中华人","中华人民","中华人民共","中华人民共和","中华人民共和国",,"中华人民共和国公"),词库中的最长匹配字符串是"中华人民共和国",那么就此切分开,扫描器推进到"公"字. 数据结构: 选择什么样的数据结构对性能影响很大.我采用Hashtable _rootTable记录词库.键值对为(键,插入次数).对每一个词语,如果该词语有N个字,则将该词语的1,1~2,1~3,......1~N个字作为键,插入_rootTable中.而同一个键如果重复插入,则后面的值递增. 三、程序 具体程序如下(程序中包含权重,插入次数等要素,目前的算法并没有利用这些.可以借此写出更有效的分词算法): ChineseWordUnit.cs //struct--(词语,权重)对 1 public struct ChineseWordUnit 2 { 3 private string _word; 4 private int _power; 5 6 /**//// <summary> 7 /// 中文词语单元所对应的中文词。 8 /// </summary> 9 public string Word 10 { 11 get 12 { 13 return _word; 14 } 15 } 16 17 /**//// <summary> 18 /// 该中文词语的权重。 19 /// </summary> 20 public int Power 21 { 22 get 23 { 24 return _power; 25 } 26 } 27 28 /**//// <summary> 29 /// 结构初始化。 30 /// </summary> 31 /// <param name="word">中文词语</param> 32 /// <param name="power">该词语的权重</param> 33 public ChineseWordUnit(string word, int power) 34 { 35 this._word = word; 36 this._power = power; 37 } 38 } ChineseWordsHashCountSet.cs //词库容器 1 /**//// <summary> 2 /// 记录字符串出现在中文字典所录中文词语的前端的次数的字典类。如字符串“中”出现在“中国”的前端,则在字典中记录一个次数。 3 /// </summary> 4 public class ChineseWordsHashCountSet 5 { 6 /**//// <summary> 7 /// 记录字符串在中文词语中出现次数的Hashtable。键为特定的字符串,值为该字符串在中文词语中出现的次数。 8 /// </summary> 9 private Hashtable _rootTable; 10 11 /**//// <summary> 12 /// 类型初始化。 13 /// </summary> 14 public ChineseWordsHashCountSet() 15 { 16 _rootTable = new Hashtable(); 17 } 18 19 /**//// <summary> 20 /// 查询指定字符串出现在中文字典所录中文词语的前端的次数。 21 /// </summary> 22 /// <param name="s">指定字符串</param> 23 /// <returns>字符串出现在中文字典所录中文词语的前端的次数。若为-1,表示不出现。</returns> 24 public int GetCount(string s) 25 { 26 if (!this._rootTable.ContainsKey(s.Length)) 27 { 28 return -1; 29 } 30 Hashtable _tempTable = (Hashtable)this._rootTable[s.Length]; 31 if (!_tempTable.ContainsKey(s)) 32 { 33 return -1; 34 } 35 return (int)_tempTable[s]; 36 } 37 38 /**//// <summary> 39 /// 向次数字典中插入一个词语。解析该词语,插入次数字典。 40 /// </summary> 41 /// <param name="s">所处理的字符串。</param> 42 public void InsertWord(string s) 43 { 44 for(int i=0;i<s.Length;i++) 45 <
|