设为首页 加入收藏 网站搜索 繁體中文 中国建站网 — 站长资源平台

编写简单的中文分词程序

来源网络收集 作者:佚名 时间:2007-4-25 23:05:17 该文得分0

几个月之前,在网上找到了一个中文词库素材(几百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            {
46                string _s = s.Substring(0,i+1);
47                this.InsertSubString(_s);
48            }
49        }
50
51        /**//// <summary>
52        /// 向次数字典中插入一个字符串的次数记录。
53        /// </summary>
54        /// <param name="s">所插入的字符串。</param>
55        private void InsertSubString(string s)
56        {
57            if (!_rootTable.ContainsKey(s.Length)&&s.Length>0)
58            {
59                Hashtable _newHashtable = new Hashtable();
60                _rootTable.Add(s.Length,_newHashtable);
61            }
62            Hashtable _tempTable = (Hashtable)_rootTable[s.Length];
63            if (!_tempTable.ContainsKey(s))
64            {
65                _tempTable.Add(s,1);
66            }
67            else
68            {
69                _tempTable[s]=(int)_tempTable[s]+1;
70            }
71        }
72    }
 

ChineseParse.cs //分词器

 1    /**//// <summary>
 2    /// 中文分词器。
 3    /// </summary>
 4    public class ChineseParse
 5    {
 6        private static ChineseWordsHashCountSet _countTable;
 7
 8        static ChineseParse()
 9        {
10            _countTable = new ChineseWordsHashCountSet();
11            InitFromFile("ChineseDictionary.txt");
12        }
13
14        /**//// <summary>
15        /// 从指定的文件中初始化中文词语字典和字符串次数字典。
16        /// </summary>
17        /// <param name="fileName">文件名</param>
18        private static void InitFromFile(string fileName)
19        {
20            string path = Directory.GetCurrentDirectory() +@"\" + fileName;
21            if (File.Exists(path))
22            {
23                using (StreamReader sr = File.OpenText(path))
24                {
25                    string s = "";
26                    while ((s = sr.ReadLine()) != null)
27                    {
28                        ChineseWordUnit _tempUnit = InitUnit(s);
29                        _countTable.InsertWord(_tempUnit.Word);
30                    }
31                }
32            }
33        }
34
35        /**//// <summary>
36        /// 将一个字符串解析为ChineseWordUnit。
37        /// </summary>
38        /// <param name="s">字符串</param>
39        /// <returns>解析得到的ChineseWordUnit</returns>
40        private static ChineseWordUnit InitUnit(string s)
41        {
42            Regex reg = new Regex(@"\s+");
43            string[] temp = reg.Split(s);
44            if (temp.Length!=2)
45            {
46                throw new Exception("字符串解析错误:"+s);
47            }
48            return new ChineseWordUnit(temp[0],Int32.Parse(temp[1]));
49        }
50
51        /**//// <summary>
52        /// 分析输入的字符串,将其切割成一个个的词语。
53        /// </summary>
54        /// <param name="s">待切割的字符串</param>
55        /// <returns>所切割得到的中文词语数组</returns>
56        public static string[] ParseChinese(string s)
57        {
58            int _length = s.Length;
59            string _temp = String.Empty;
60            Array

[1] [2] [3]  下一页

相关文章
广告赞助
网友评论

共有 0 位网友发表了评论,平均得分: 0 查看完整内容

用户名:

分 值:100分 85分 70分 55分 40分 25分 10分 0分

内 容:

(注“”为必填内容。) 验证码: 验证码,看不清楚?请点击刷新验证码