当前位置:编程学习 > asp >>

基于.NET的分词软件设计与实现V1.0--总体思路及算法实现

首先介绍一下这个分词软件的总体思路。

  查阅了网上的一些相关资料,普遍采用的都是“正向最大匹配算法”和“逆向最大匹配算法”,不了解的朋友先来这里看下两个算法的基本思想:

  正向最大匹配算法基本思想是:首先在词库里查找文本是否存在,如果存在,直接提取出来,而如果不存在,则删除文本的最后一个字,检查是否是单字,若是输出此字并将短语减去此字,若不是则继续判断看字库是否存在这个词,如此反复循环,直到输出一个词,这样就可以将一个短语分成词语的组合了。

  而逆向最大匹配算法自然是相反的,如果发现待分词文本在词典中不存在,那么删除文本的第一个字,进行再次匹配操作。

  实验证明:正向最大匹配对歧义识别比较差,分词的准确性不高,所以我的这个分词软件使用了“逆向最大匹配算法”的思想。

  ---------------------------------------------------------------------------------------------------------------------------

  但如果将拿到任意的一段文本作为一个整体直接使用逆向最大匹配算法进行拆分,那么复杂度可想而知,效率肯定是惨不忍睹的,那么应该如何进行分词呢,这里我采用了“标点断句法”,即用正则表达式匹配文本,找到文本中的标点,然后以此为标志进行断句,把一段很长的文本分割成一段一段的小文本,然后再使用逆向最大匹配算法进行分词操作。

  好了,有了思路就要付诸实践了:

  1、首先,我从网上下载了“标点符号词典”。截图如下:

当然,这是中文的标点自然好说,但由于是使用正则表达式进行匹配,所以对于英文的标点就不能这么对待了,这里我进行了转义处理:

这样可以防止这些英文标点被正则表达式解析为具有特殊意义的字符。

  2、利用正则表达式断句:将待分词文本与标点符号词典进行匹配,并以匹配成功的位置为标识进行断句。

 1     /// <summary>

 2     /// 创建标点符号组成的字符串

3     /// </summary>

4     /// <param name="dictPath">标点符号词典存放路径</param>

5      string GetPunctuationDictionary(string dictPath)

6     {

7         StringBuilder strBuilder = new StringBuilder();

 8         foreach (string s in File.ReadAllLines(dictPath))

9         {

10             strBuilder.Append(s);

11         }

12         return strBuilder.ToString();

13     }

 1    /// <summary>

2    /// 标点符号字符串

3    /// </summary>

4     string _splitters;

6    /// <summary>

7    /// 获得字符串中匹配的标点符号的集合(去除重复项)

8    /// </summary>

9     List<string> GetMatchedSpiltters()

10    {

11        List<string> matchedSplitters = new List<string>();

12        Regex regex = new Regex("[" + _splitters + "]");

13        foreach (var item in regex.Matches(_inputStr))

14        {

15            if (!matchedSplitters.Contains(item.ToString()))

16                matchedSplitters.Add(item.ToString());

17        }

18        return matchedSplitters;

19    }  如“示例:这是我做的分词软件,谢谢使用!”这句话,经过上述的匹配操作后,得到的matchedSplitters即为:,和!组成的集合。

       3、以正则表达式匹配的标点位置为标志,去除文本标点。

 1         /// <summary>

 2         /// 去除待分词文本中的标点符号并分割成独立的句子(去除空串)

3         /// </summary>

4          List<string> GetStripedPunctuationString()

5         {

6             List<string> matchedSplitters = GetMatchedSpiltters();

7             foreach (string str in matchedSplitters)

8             {

9                 _inputStr = _inputStr.Replace(str, " ");

10             }

11             return _inputStr.Split(new string[] { " " },                       StringSplitOptions.RemoveEmptyEntries).ToList();

12         }  如“示例:这是我做的分词软件,谢谢使用!”经过上述操作就变为了“示例 这是我做的分词软件 谢谢使用 ”

  4、首先判断待分词文本是否在分词词典中存在,若存在,则保存在待输出集合中,否则采用逆向最大匹配算法对待分词文本进行分词操作。


   /// <summary>  

 /// 采用逆向匹配算法对字符串进行分词操作  

/// </summary>  

/// <param name="str">待分词的字符串</param>  

 List<string> Spiltter(string str)  

 {      

 //输出结果集      

List<string> result = new List<string>();      

if (str.Length == 1)      

{          

result.Add(str);          

return result;      

}             

//删除第一个字      

 string initStr = str.Remove(0, 1);      

int l = 0;      

while (!string.IsNullOrEmpty(initStr))      

{          

for (int i = 1; i < str.Length; i++)          

 {              

//如果是单字或者在词典中存在              

if (initStr.Length == 1 || _dict.Keys.Contains(initStr))              

{                  

 result.Add(initStr + "\");                  

 l += initStr.Length; &n

补充:Web开发 , ASP.Net ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,