当前位置: 首页 > 图文教程 > 网络编程 > ASP.NET > asp.NET 脏字过滤算法 修改版

ASP.NET
ASP.NET超凡的代码控制(二)
剖析ASP.NET下部构造(一)
剖析ASP.NET下部构造(二)
ASP.NET的Web controls(一)
ASP.NET的Web controls(二)
如何在页面上动态的生成 WebForm控件
再议正则表达式(这次是在asp.net 上的应用)
利用.NET框架简化发布和解决DLL Hell问题(1)
利用.NET框架简化发布和解决DLL Hell问题(2)
在ASP+中访问数据库
通过事例学习.net的WebForms技术(一)
通过事例学习.net的WebForms技术(二)
如何在aspx中得到在存储过程中的的数值(兼答jspfuns的问题)
如何得到一个汉字和字母组合的字符串的准确的长度(asp.net 版本的)
ASP+中取代ASP的RS(Remote Scripting)技术的Framework
通过事例学习.net的WebForms技术(三)
通过事例学习.net的WebForms技术(四)
通过事例学习.net的WebForms技术(五)
通过网络域名得到这台主机的IP地址
查看服务器磁盘、文件的aspx

ASP.NET 中的 asp.NET 脏字过滤算法 修改版


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2010-01-10   浏览: 237 ::
收藏到网摘: n/a

我们网站的脏字字典中大概有600多个词,而且会发生变化,因此简单的在数据新增/修改的时候做一次脏字过滤是不够的。在网站从.NET 1.1到2.0改版的时候,对新版的测试发现旧的脏字过滤算法耗费的时间过长,需要做一些优化。 旧的算法是简单对每一个脏字调用一遍 string.replace,当然是用了StringBuilder。http://www.ruanchen.com/"codetitle">复制代码 代码如下:

private Dictionary<string, object> hash = new Dictionary<string, object>();
private BitArray firstCharCheck = new BitArray(char.MaxValue);
private BitArray allCharCheck = new BitArray(char.MaxValue);
private int maxLength = 0;

其中hash只使用到了key,value都置为null。也可以使用.NET 3.5中的HashSet,或者使用Dictionary<string, int>,记录脏字的出现次数。
初始化这些数据的方法如下:
复制代码 代码如下:

foreach (string word in badwords)
{
if (!hash.ContainsKey(word))
{
hash.Add(word, null);
maxlength = Math.Max(maxlength, word.Length);
firstCharCheck[word[0]] = true;
foreach (char c in word)
{
allCharCheck[c] = true;
}
}
}

判断脏字是否出现在一个字符串中的代码如下:
复制代码 代码如下:

int index = 0;
int offset = 0;
while (index < text.Length)
{
if (!firstCharCheck[text[index]])
{
while (index < text.Length - 1 && !firstCharCheck[text[++index]]) ;
}
for (int j = 1; j <= Math.Min(maxlength, text.Length - index); j++)
{
if (!allCharCheck[text[index + j - 1]])
{
break;
}
string sub = text.Substring(index, j);
if (hash.ContainsKey(sub))
{
return true;
}
}
index++;
}
return false;

替换的代码就不贴了,跟判断包含类似,只不过不能发现一个脏字后就退出循环。如果出现脏字的可能不是很高,就没有必要创建一个临时的StringBuilder。
进一步,可以通过借鉴.NET源码中string.GetHashCode()的实现,避免一次Substring的调用,提高性能。也可以设计递进的HashCode实现,比如"helloworld"可以用"helloworl"的hash进一步计算,优化效率。
另外,也可以抛弃Hash,改用排序过的string[],用BinarySearch来判断sub是否为脏字。BinarySearch的结果是可以递进的,即可以用查找"helloworl"的结果来加速判断"helloworld"。 (已测试,700个脏字,BinarySearch的效率有时会低很多。)
最后发一点牢骚,当初最早发的时候(http://www.ruanchen.com/rticle/20576.htm),仅仅是为了说明下自己的算法,具体的代码甚至还有一点错误。两个事情让我觉得心里不很爽,一个是被乱七八糟的无数网站转载而不说明出处,导致我后来的改进和错误修正达不到效果,二是一些人都愿意看到最终的代码,而不是理解我想要表达的最核心的设计,然后自己去考虑实现。

评论 (0) All

登陆 还没注册?