编写简单的中文分词程序(转载)

几个月之前,在网上找到了一个中文词库素材(几百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 {
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>

4 public class ChineseWordsHashCountSet
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();
60_rootTable.Add(s.Length,_newHashtable);
61}

62Hashtable_tempTable=(Hashtable)_rootTable[s.Length];
63if(!_tempTable.ContainsKey(s))
64{
65_tempTable.Add(s,1);
66}

67else
68{
69_tempTable[s]=(int)_tempTable[s]+1;
70}

71}

72}

ChineseParse.cs //分词器

1 /**/ ///<summary>
2///中文分词器。
3///</summary>

4 public class ChineseParse
5 {
6privatestaticChineseWordsHashCountSet_countTable;
7
8staticChineseParse()
9{
10_countTable=newChineseWordsHashCountSet();
11InitFromFile("ChineseDictionary.txt");
12}

13
14/**////<summary>
15///从指定的文件中初始化中文词语字典和字符串次数字典。
16///</summary>
17///<paramname="fileName">文件名</param>

18privatestaticvoidInitFromFile(stringfileName)
19{
20stringpath=Directory.GetCurrentDirectory()+@"\"+fileName;
21if(File.Exists(path))
22{
23using(StreamReadersr=File.OpenText(path))
24{
25strings="";
26while((s=sr.ReadLine())!=null)
27{
28ChineseWordUnit_tempUnit=InitUnit(s);
29_countTable.InsertWord(_tempUnit.Word);
30}

31}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值