ACオートマトン:マルチパターンマッチング敏感ワードフィルタリングを達成するためにどのように?

ACオートマトン:マルチパターンマッチング敏感ワードフィルタリングを達成するためにどのように?

文字列照合アルゴリズムは、ユーザーが入力したこのテキストを見つけるために、文字列照合アルゴリズムによってテキストを入力した後、辞書に敏感な単語を維持することによって、***があれば、使用することを、敏感な言葉が含まれています代替

高パフォーマンスの影響を受けやすいワードフィルタリングシステムを達成するためにどのように?複数の文字列マッチングアルゴリズム

シングルモードに基づいて敏感な単語列をフィルタリングし、トライを達成

BF、RK、BM、KMP、トライ木、最初の4つのパターン文字列マッチングアルゴリズムは、唯一のトライは、マルチパターンマッチングアルゴリズムであります

呼ばれる単一のパターン文字列は、文字列であり、マスターパターン文字列照合の間に、複数文字列マッチングは、マスターパターン文字列と文字列の複数の間で行われます

トライはそれをフィルタリングしてどのように敏感な言葉?

言葉に敏感な文字が動的に更新され、唯一のユーザーはテキストの内容、主な文字列として、ユーザー入力を入力したときに動的に最初から、ルックトライ木を更新する必要がある場合は前処理に敏感な言葉は、トライ木構造を構築しますトライリーフノードにマッチしたときに遭遇したときの文字に一致しない、またはメイン文字列は次の移動の開始位置と一致したときに、次の文字が始まる文字で、トライでのマッチング、文字を開始トライで試合を再開

より効率的な古典的な複数文字列マッチングアルゴリズム:ACオートマトン

単純な文字列照合アルゴリズムを一致する単一の文字列としてトライ及びAC自動機との間の関係、同じとKMPアルゴリズムが、唯一のマルチモードの文字列のトライ、AC自動機械は、トライの上になるように、プラス次の類似したKMPの配列が、現在次のアレイは、木々に内蔵されてベール

public class AcNode{
	public char data;
	public AcNode[] children = new AcNode[26];//字节集只包含a~z这26个字符
	public boolean isEndingChar = false; //结尾字符为true
	public int length = -1;   //当isEndingChar = true时,记录模式串长度
	public AcNode fail;//失败指针
	public AcNode(char data){
		this.data = data;
	}
}

ACオートマトン構築物は、2つの操作を含みます。

  • トライに構築されたパターン列の複数
  • トライ木構築故障ポインタ(配列KMPの故障に対応する次関数)

どのようにトライポインタを構築した後、その上にビルドに失敗しますか?

このような4つのパターン列c、BC、BCD、ABCDがありますが、メインの文字列ABCDです

ルート

ABC

BC

cD

D

トライ木の各ノードはトライノードに沿ってp個のGoは、ノードCが赤色の場合、故障へのポインタを有し、ポインタpは文字列abcの障害がルートノードから来る赤こと、すべてのプレフィックスを有するパターン列が形成されています最長パターンマッチングサブストリングは、接尾辞に一致するBC、その文字列にポイントを矢印

最長の部分文字列は接尾辞接頭サブストリングは、パターン文字列、サブサフィックスと一致した場合、他のパターンマッチングにそれらを取るために、サフィックス文字列abcの接尾サブストリング2つのBC、Cが一致しますサフィックス文字列の一致するサブストリングが接尾サブストリングから最長一致が最も長い部分文字列が接尾辞と一致している見つけることができますと呼ばれます

最後のノードのプレフィックスに対応する最長のサブストリングサフィックスパターン文字列と一致するノードへのポインタpのポインティングが第2の点C cから最初に失敗しました

建設プロセスは、ポインタがツリーをレイヤにおける処理で失敗し、ルートには、ポインタを失敗した場合、自分自身にポイントではnullであり、

ときに我々は、その子ノードの障害を見つける方法についてのポインタが、失敗したノードpポインタのために祈る必要がありますか?

ノードqに失敗したポインタセットノードpポイントは、文字を対応するp- PCの子ノードが子ノードQCノードは、Qが発見された場合、ノードPCと対応する文字が対応する、子ノードqで見つけることができるかどうかを確認しますノードqが文字サブノードが含まれるノードPCの文字に等しいでない場合、同じ文字は、QCノードポインタのノードPCポイントを失敗するので、Q = Q - >フェイル(失敗ポインタを示すフェイル)、Q =ルートまで検索を続けますこれまでのところ、同じ文字の子ノードが見つからない場合は、ルートにノード障害PCの指し示すポインタを聞かせて

ポインタを構築するために失敗します:
public void buildFailurePointer(){
	Quene<AcNode> quene = new LinkedList<>();
	root.fail = null;
	quene.add(root);
	while(!quene.isEmpty()){
		AcNode p = quene.remove();
		for(int i = 0 ; i < 26 ; ++i){
			AcNode pc = p.children[i];
			if(pc == null) continue;
			if(p == root){
			pc.fail = root;
			}else{
				AcNode q = p.fail;
				while(q != null){
					AcNode qc = q.children[pc.data - 'a'];
					if(qc != null){
						pc.fail = qc;
						break;
					}
					q = q.fail;
				}
				if(q == null){
					pc.fail = root;
				}
			}
			quene.add(pc);
		}
	}
}
メインACオートマトン上の文字列を一致させる方法は?

Iからメインストリングが開始= 0のプロセスは、ACオートマトンは、p =ルートポインタから開始し、パターン文字列は、Bは、メインの文字列であると仮定されます

  • ノードは、pによって指し示さ存在する場合、Bに等しい。[i]は、子ノードX、ポインタが必要なとき、ポインタはパターン文字列、後処理を終了失敗したパスの一連の検出に失敗P更新点x、I + 1、続けます
  • ないノードは、p = B [i]の子ノードで指さ場合は、そのP = P - >失敗していること

出力コードと一致するコードがある:(メインストリング内の位置の文字列パターンマッチング缶の各出現)

public void match(char[] text){     //text是主串
	int n = text.length;
	AcNode p = root;
	for(int i = 0 ; i < n ; ++i){
		int idx = text[i] - 'a';
		while(p.children[idx] == null && p != root){
			p = p.fail;        //失败指针发挥作用的地方
		}
		p = p.children[idx];
		if(p == null)  p = root;   //如果没有匹配的,从root开始重新匹配
		AcNode tmp = p ;
		while (tmp != root){  //打印出可以匹配的模式串
			if(tmp.isEndingChar == true){
				int pos = i - tmp.length+1;
				System.out.println("匹配起始下标" + pos + ";长度" + tmp.length);
			}
			tmp = tmp.fail;
		}
	}
}

敏感ワードフィルタリングシステムACオートマトン単一パターン文字列照合方法よりも効率的かどうか?

AC敏感言葉はトライ失敗したポインタを含む構築自動機械を構築しました

ビューの複雑さの観点から、トライ有するACオートマトン一致の効率は、のように、実際には、故障ポインタのほとんどのルートを指し、

https://www.cnblogs.com/sclbgw7/p/9260756.html

https://www.cnblogs.com/hyfhaha/p/10802604.html

公開された75元の記事 ウォンの賞賛9 ビュー9185

おすすめ

転載: blog.csdn.net/ywangjiyl/article/details/104525867