ActionScript 3敏感词过滤算法
发布时间:2020-12-15 07:21:17 所属栏目:百科 来源:网络整理
导读:最简单的敏感词查找办法应是 for each ( var i in 敏感词列表){ if (原字符串.indexOf(i)!=- 1 ) return true ;} //end for return false ; 也包括使用正则的简单查找办法 我们需要了解的是,即使正则和indexOf是flash自带方法、效率较高,它们仍然需要逐字
最简单的敏感词查找办法应是 for each(var i in 敏感词列表){
if(原字符串.indexOf(i)!=-1)return true;
}//end for
return false;
也包括使用正则的简单查找办法 我们需要了解的是,即使正则和indexOf是flash自带方法、效率较高,它们仍然需要逐字查询字符串 下面办法通过预计算将敏感词做成树型结构,方便查询。能将运行时时间代价降低到O(n)左右,藉此提高发现敏感词的速度。 package {
import flash.display.Sprite;
import flash.events.Event;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.utils.Dictionary;
public class SensitiveWordFilter extends Sprite {
private var loader:URLLoader = new URLLoader();
private var wordsVec:Vector.<String> = new Vector.<String>;
private var testFilter:WordFilter = new WordFilter;
public function SensitiveWordFilter() {
loader.addEventListener(Event.COMPLETE,OnComplete);
loader.load(new URLRequest("load_config_complete.txt"));
}
private function OnComplete(e:Event):void {
var txt:String = loader.data;
var arr:Array = txt.split("rn");
arr.sort(onSort);
for each (var str:String in arr)
{
wordsVec.push(str);
}
//trace(wordsVec);
testFilter.regSensitiveWords(wordsVec);
var strTest:String = "总理是朱八重,朱鎔基shi总理。曾经朱鎔基是总理,曾经有个恐怖组织叫做东突厥斯坦恐怖组织";
trace(testFilter.findSensitiveWordsIn(strTest));
}
private function onSort(a:String,b:String):int {
if(a.length > b.length)
{
return 1;
} else {
return -1;
}
}
}
}
下面这个类主要是建立敏感词库的存储数结构: // ActionScript file
package {
public class TreeNode {
private var data:Object;
public var isLeaf:Boolean;
public var parent:TreeNode;
public var value:String;
public function TreeNode(){
data={};
isLeaf=true;
}//end of Function
public function getChild(name:String):TreeNode{
return data[name];
}//end of Function
public function setChild(key:String):TreeNode{
var node:TreeNode = new TreeNode;
data[key]=node;
node.value=key;
node.parent=this;
return node;
}//end of Function
public function getFullWord():String{
var rt:String = this.value;
var node:TreeNode = this.parent;
while(node){
rt=node.value+rt;
node=node.parent;
}//end while
return rt;
}//end of Function
}//end of class
}
建立好树结构以后就可以从文本中读取数据,然后将数据存储成树结构即可: package {
import flash.events.Event;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.utils.Dictionary;
public class WordFilter {
private var treeRoot:TreeNode;
public function regSensitiveWords(words:Vector.<String>):void{
//这是一个预处理步骤,生成敏感词索引树,功耗大于查找时使用的方法,但只在程序开始时调用一次。
treeRoot=new TreeNode();
treeRoot.value="";
var words_len:int = words.length;
for(var i:int = 0;i<words_len;i++){
var word:String = words[i];
var len:int = word.length;
var currentBranch:TreeNode = treeRoot;
for(var c:int = 0;c<len;c++){
currentBranch.isLeaf=false;
var char:String = word.charAt(c);
var tmp:TreeNode = currentBranch.getChild(char);
if(tmp){
if(tmp.isLeaf){
throw new Error("长词在短词后被注册。已经有以("+tmp.getFullWord()+")开头的敏感词存在,当前正在注册第"+i+"个词("+word+")");
}//end if
currentBranch=tmp;
}else {
currentBranch=currentBranch.setChild(char);
}//end if
}//end for
if(!currentBranch.isLeaf){
throw new Error("短词在长词后被注册。已经有以("+word+")开头的敏感词存在,当前正在注册第"+i+"个词");
}//end if
//trace(currentBranch.value);
}//end for
}//end of Function
public function findSensitiveWordsIn(og:String):String{
var ptrs:Array = new Array//嫌疑列表,但凡前几个字匹配成功的节点都放在这里
var len:int = og.length;
var tmp:TreeNode;
for(var c:int = 0;c < len; c++){
var char:String = og.charAt(c);
//如果嫌疑列表内有数据,先对其进行检验,检查char是否是嫌疑列表中某节点的下一个字
var p:int = ptrs.length;
while(p--){
var node:TreeNode = ptrs.shift();
tmp=node.getChild(char);
if(tmp){
if(tmp.isLeaf){
var tmpLength:int = tmp.getFullWord().length;
trace(tmp.getFullWord());
var tmpStr:String;
for(var i:int = 0; i < tmpLength; ++i)
{
tmpStr += "*";
}
tmpStr = tmpStr.substr(tmpStr.length - tmpLength,tmpStr.length - 1);
og = og.replace(tmp.getFullWord(),tmpStr);
//return tmp.getFullWord()+" @["+c+"]" + "######" + og;
}//end if
//从node开始,敏感词的下一个字也被匹配到,并且已经完整地匹配了一个敏感词,可以返回
ptrs.push(tmp);
//trace(og.replace(,"*"));
//从node开始,下一个字也匹配到了,但还没有完整地匹配一个敏感词,那么将下一个字的节点压入嫌疑列表
}//end if
}//end while
//之后从treeRoot开始查找。因treeRoot的子项是所有敏感词的第一个字,这里在尝试匹配是否有与char相同的敏感词第一字
tmp=treeRoot.getChild(char);
if(tmp){
//var tempLength:int = tmp.getFullWord().length;
//var tempStr:String = null;
//for(var j:int; j < tempLength; ++j)
//{
//tempStr += "*";
//}
//trace(tempStr);
//og = og.replace(tmp.getFullWord(),tempStr);
if(tmp.isLeaf){
return char+" @["+c+"]" + "######" + og;
}//end if
//如果是一个字的敏感词,直接返回
ptrs.push(tmp);
//如果匹配上了非单字敏感词的第一个字,那么将其加入嫌疑列表
}//end if
}//end for
return og;
}//end of Function
}//end of class
}//end of file
大致算法如此,以后有时间再来优化。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |