文本中关键字匹配算法
来源:互联网 发布:中国程序员联盟 编辑:程序博客网 时间:2024/05/01 22:06
给定一定数量的关键字,对任一篇文本,寻找文本中包含哪些关键字
例如关键字集合如下:
而待检测的文本如下:
当前算法的目的就是从test.txt中快速的检索有没有给定的keyWord.txt中的关键字
具体的代码下载地址是:http://download.csdn.net/detail/sinat_22013331/9551006,这部分代码是用C#写的,如果要java或者其他语言的版本,可以对照着改动一些。
这个文本处理需要一个算法, 普通的文本处理直接去遍历所有的关键字,但是这种算法太复杂,时间复杂度太高。
之前的文章中有说过,实际用到的算法,为了加快执行速度,都是在时间和空间上做的兑换,用存储空间的增加来换取执行时间的减小。
这里同样可以,通过增加存储空间来减少程序执行时间。
可以选择开一个数组,数组的长度是char类型的最大长度加一。
数组的相应字符对应位置上的数值用二进制表示。假设关键字的长度最长为15,则可以用两个字节的数字来表示,也就是一个short类型。
假设数字为 0000 0000 0010 0110, 也就是38。则表示当前这个字符,可能出现在关键字的第2,3,6位上。由此做倒排索引,可以更方便的得到答案。
//对应位上的值存放的是每个字符在对应位数上是否存在敏感词,//比如fastPositionCheck[7] = 38, 也就是0010 0110 表示某个ascll码为7的字符可能出现在关键字的第2,3,6位上private short[] fastPositionCheck = new short[char.MaxValue + 1];
这个实现方案可以变成:首先创建一个关键字字典,在这个字典中包含所有的关键字。同时在这个字典中提供针对某个字符的快速检验方法,比如说查看当前关键字是否出现在第一位。
创建的字典如下:
//存放所有关键词private HashSet<string>[] words = new HashSet<string>[ char.MaxValue + 1 ];
//对应位上的值存放的是每个字符在对应位数上是否存在敏感词, //比如fastPositionCheck[7] = 35, 也就是0010 0011 表示某个ascll码为7的字符可能出现在关键字的第1,2,6位上 private short[] fastPositionCheck = new short[char.MaxValue + 1]; //存放以某个字符为第一位的关键词的长度 private short[] fastLengthCheck = new short[char.MaxValue + 1];
于是字典建立完成之后,就要将所有的关键字添加到字典中,在添加的时候,对各种存储空间赋值。操作如下:
/// <summary> /// 向字典中添加关键词 /// </summary> /// <param name="word"></param> /// <returns></returns> public bool AddWord( string word ) { bool result = false; try { maxStoreWordLength = Math.Max(maxStoreWordLength, word.Length); minStoreWordLength = Math.Min(minStoreWordLength, word.Length); //这些运算符的运用简直了,神来之笔 for (int i = 0; i < word.Length; i++) { fastPositionCheck[word[i]] |= (short)(1 << i); } //记录以某个字开头的关键字的长度信息,左移位数长度为该字符串长度减一 fastLengthCheck[word[0]] |= (short)(1 << (word.Length - 1)); if (words[word[0]] == null) { words[word[0]] = new HashSet<string>(); } if (!words[word[0]].Contains(word)) { words[word[0]].Add(word); } result = true; } catch (Exception e) { Console.WriteLine(e.Message); } return result; } }
在字典的使用中,前面已经讲过KMP算法了,这里的思路有点像,还是从string的第一个字符开始,逐渐向后遍历,直到最后一个字符。遍历的时候作快速判定,此时的判定依据就是前面提到的几个数组。具体代码如下:
public void CheckNormalWord(string text ) { int index = 0; while (index < text.Length) { //首先判断当前字符是否是某关键字的第一个字符,不是时就继续向下遍历 if ((keywordDict.FastCheck[text[index]] & 1) == 0) { do { index++; } while ( (index < text.Length) && ((keywordDict.FastCheck[text[index]] & 1) == 0) ); if (index >= text.Length) { break; } } //此时已经判定,当前的这个字符会出现在关键词的第一位上 //在判断 char begin = text[index]; int jump = 1; for (int j = 0; j <= Math.Min(keywordDict.MaxWordLength, text.Length - index - 1); j++) { char current = text[index + j]; //判断当前字符是否会出现在关键字的对应位上,实现快速判断 if ((keywordDict.FastCheck[current] & (1 << Math.Min(j, keywordDict.MaxWordLength))) == 0) { break; } //当判决的长度大于关键字的最小长度时,当前的截取字符串有可能会是关键字,要做详细判定 if (j + 1 >= keywordDict.MinWordLength) { if ((keywordDict.FastLength[begin] & (1 << Math.Min(j, keywordDict.MaxWordLength))) > 0) { string sub = text.Substring(index, j + 1); //在字典中搜索判断,得出结论。同时给出跳转位数,供下一次跳转用 if (keywordDict.Words[begin] != null && keywordDict.Words[begin].ContainsKey(sub)) { jump = sub.Length; Console.WriteLine(sub); } } } } index += jump; } }
这样就实现了整个文本中搜索指定关键字的算法。具体的代码详见https://github.com/BLYang7/HighlightKeyword
- 文本中关键字匹配算法
- KMP文本匹配算法
- 多关键字匹配算法
- 中文文本关键字分割算法
- 匹配文本中获取网址
- mysql 关键字匹配算法 SQL 实例
- 字符串关键字搜索匹配提取处理算法
- 关键字匹配之BF算法-python实现
- 从文本中找到匹配的行
- vim中选择匹配文本删除技巧
- 一行文本中括号的匹配情况
- 从文本中查找匹配行
- vim中选择匹配文本删除技巧
- 内容过滤中关键字的匹配函数
- 改变文本中关键字的颜色
- 关于BF算法的理解——文本匹配算法
- 关于KMP算法的理解——文本匹配算法
- 对于BM算法的理解——文本匹配算法
- Java四种引用
- 文本分类与SVM
- Dagger2入坑之旅 二
- JAVA枚举详解
- CSS——基础知识
- 文本中关键字匹配算法
- Joining data
- ssl socket 抓包验证
- 浅析Java注解
- JAVA代码规范
- Android开发笔记之四大组件琐碎知识回顾总结
- Android消息循环机制源码分析
- hdu 5444 Elven Postman(二叉树的遍历)
- C# ListView控件制作表格:添加行,删除行,右键删除行