如何编写中文分词程序?
一、词库
词库大概有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--(词语,权重)对
1publicstructChineseWordUnit

2...{
3privatestring_word;
4privateint_power;
5

6/**//**//**////<summary>

7/**////中文词语单元所对应的中文词。

8/**////</summary>
9publicstringWord

10...{
11get

12...{
13return_word;
14}
15}
16

17/**//**//**////<summary>

18/**////该中文词语的权重。

19/**////</summary>
20publicintPower

21...{
22get

23...{
24return_power;
25}
26}
27

28/**//**//**////<summary>

29/**////结构初始化。

30/**////</summary>

31/**////<paramname="word">中文词语</param>

32/**////<paramname="power">该词语的权重</param>
33publicChineseWordUnit(stringword,intpower)

34...{
35this._word=word;
36this._power=power;
37}
38}


ChineseWordsHashCountSet.cs//词库容器



1/**//**//**////<summary>

2/**////记录字符串出现在中文字典所录中文词语的前端的次数的字典类。如字符串“中”出现在“中国”的前端,则在字典中记录一个次数。

3/**////</summary>
4publicclassChineseWordsHashCountSet

5...{

6/**//**//**////<summary>

7/**////记录字符串在中文词语中出现次数的Hashtable。键为特定的字符串,值为该字符串在中文词语中出现的次数。

8/**////</summary>
9privateHashtable_rootTable;
10

11/**//**//**////<summary>

12/**////类型初始化。

13/**////</summary>
14publicChineseWordsHashCountSet()

15...{
16_rootTable=newHashtable();
17}
18

19/**//**//**////<summary>

20/**////查询指定字符串出现在中文字典所录中文词语的前端的次数。

21/**////</summary>

22/**////<paramname="s">指定字符串</param>

23/**////<returns>字符串出现在中文字典所录中文词语的前端的次数。若为-1,表示不出现。</returns>
24publicintGetCount(strings)

25...{
26if(!this._rootTable.ContainsKey(s.Length))

27...{
28return-1;
29}
30Hashtable_tempTable=(Hashtable)this._rootTable[s.Length];
31if(!_tempTable.ContainsKey(s))

32...{
33return-1;
34}
35return(int)_tempTable[s];
36}
37

38/**//**//**////<summary>

39/**////向次数字典中插入一个词语。解析该词语,插入次数字典。

40/**////</summary>

41/**////<paramname="s">所处理的字符串。</param>
42publicvoidInsertWord(strings)

43...{
44for(inti=0;i<s.Length;i++)

45...{
46string_s=s.Substring(0,i+1);
47this.InsertSubString(_s);
48}
49}
50

51/**//**//**////<summary>

52/**////向次数字典中插入一个字符串的次数记录。

53/**////</summary>

54/**////<paramname="s">所插入的字符串。</param>
55privatevoidInsertSubString(strings)

56...{
57if(!_rootTable.ContainsKey(s.Length)&&s.Length>0)

58...{
59Hashtable_newHashtable=newHashtable();
