-
DFA算法C#实现
搬运自:https://www.cnblogs.com/AlanLee/p/5329555.html
原理搜关键字:DFA算法
基本照抄了原文的JAVA代码,其中应该可以用Dictionary<string,int>来代替Hashtable,但搜到的资料都说Hashtable快得要命,虽然知道他们说的是JAVA环境,但也懒得改了,这东西实现出来不卡线程就行。
试了一下,初始化一个一万九千多行的文本大概需要40毫秒,然后在一个大约二万字的文本内搜索100多个关键词(随机插入测试的,话说处理这个测试文本还花了一些功夫,第一版的随机插入,时不时就会插入到前面插入的关键词中间去,导致匹配出来的数量老是不对),只需要7毫秒。
1 /// <summary> 2 /// 过滤词DFA算法实现 3 /// </summary> 4 public class ForbiddentWordLibrary 5 { 6 /// <summary> 7 /// 用分行过滤词文件来初始化过滤词库 8 /// </summary> 9 /// <param name="path">文件路径</param> 10 public ForbiddentWordLibrary( string path ) 11 { 12 try 13 { 14 words = new HashSet<string>(); 15 using( var stream = new StreamReader( path, Encoding.UTF8 ) ) 16 { 17 while( !stream.EndOfStream ) 18 { 19 words.Add( stream.ReadLine().Trim() ); 20 } 21 } 22 InitLibrary(); 23 } 24 catch( Exception ex ) 25 { 26 throw ex; 27 } 28 } 29 30 /// <summary> 31 /// 找到输入字符串内所有敏感词 32 /// </summary> 33 /// <param name="input"></param> 34 /// <returns></returns> 35 public List<string> GetAllForbiddenWords( string input ) 36 { 37 List<string> result = new List<string>(); 38 for( int i = 0; i < input.Length; i++ ) 39 { 40 int length = SearchFW( input, i ); 41 if( length > 0 ) 42 { 43 result.Add( input.Substring( i, length ) ); 44 i = i + length - 1; 45 } 46 } 47 48 return result; 49 } 50 51 /// <summary> 52 /// 搜索输入的字符串,查找所有敏感词,找到则返回敏感词长度 53 /// </summary> 54 /// <param name="input">输入字符串</param> 55 /// <param name="beginIndex">查找的起始位置</param> 56 /// <returns></returns> 57 private int SearchFW( string input, int beginIndex ) 58 { 59 bool flag = false; 60 int len = 0; 61 Hashtable ht = lib; 62 for( int i = beginIndex; i < input.Length; i++ ) 63 { 64 var c = input[ i ]; 65 var obj = ht[ c.ToString() ]; 66 if( obj == null ) 67 break; 68 else 69 { 70 len++; 71 ht = (Hashtable)obj; 72 if( (int)ht[ "IsEnd" ] == 1 ) 73 flag = true; 74 } 75 } 76 77 if( !flag ) 78 len = 0; 79 80 return len; 81 } 82 83 /// <summary> 84 /// 初始化词库结构 85 /// </summary> 86 private void InitLibrary() 87 { 88 lib = new Hashtable( words.Count ); 89 var tmp = lib; 90 foreach( string k in words ) 91 { 92 for( int i = 0; i < k.Length; i++ ) 93 { 94 var c = k[ i ].ToString(); 95 if( tmp.ContainsKey( c ) ) 96 { 97 tmp = (Hashtable)tmp[ c ]; 98 } 99 else 100 { 101 var nht = new Hashtable(); 102 nht.Add( "IsEnd", 0 ); 103 tmp.Add( c, nht ); 104 tmp = nht; 105 } 106 107 if( i == k.Length - 1 ) 108 { 109 if( tmp.ContainsKey( "IsEnd" ) ) 110 tmp[ "IsEnd" ] = 1; 111 else 112 tmp.Add( "IsEnd", 1 ); 113 } 114 } 115 tmp = lib; 116 } 117 } 118 119 /// <summary> 120 /// 原始过滤词数据集 121 /// </summary> 122 private HashSet<string> words; 123 /// <summary> 124 /// 过滤词库 125 /// </summary> 126 private Hashtable lib; 127 }
栏目列表
最新更新
nodejs爬虫
Python正则表达式完全指南
爬取豆瓣Top250图书数据
shp 地图文件批量添加字段
爬虫小试牛刀(爬取学校通知公告)
【python基础】函数-初识函数
【python基础】函数-返回值
HTTP请求:requests模块基础使用必知必会
Python初学者友好丨详解参数传递类型
如何有效管理爬虫流量?
SQL SERVER中递归
2个场景实例讲解GaussDB(DWS)基表统计信息估
常用的 SQL Server 关键字及其含义
动手分析SQL Server中的事务中使用的锁
openGauss内核分析:SQL by pass & 经典执行
一招教你如何高效批量导入与更新数据
天天写SQL,这些神奇的特性你知道吗?
openGauss内核分析:执行计划生成
[IM002]Navicat ODBC驱动器管理器 未发现数据
初入Sql Server 之 存储过程的简单使用
这是目前我见过最好的跨域解决方案!
减少回流与重绘
减少回流与重绘
如何使用KrpanoToolJS在浏览器切图
performance.now() 与 Date.now() 对比
一款纯 JS 实现的轻量化图片编辑器
关于开发 VS Code 插件遇到的 workbench.scm.
前端设计模式——观察者模式
前端设计模式——中介者模式
创建型-原型模式