BMアルゴリズムは、「悪い文字ルール」と「良いサフィックスルール」という2つの基準に従って文字列マッチングを実行します。この場合、良いサフィックスルールは単独で使用でき、アルゴリズムは次のブログ投稿を参照できます。
https://www.cnblogs.com/wxgblogs/p/5701101.html
BMアルゴリズムの実装にはPython言語が使用され、実装プロセスは3つの関数、メインループ関数と2つの基準配列生成関数に分かれています。
1 def my_BM(t、p):
2 '' ' bmアルゴリズムの自己実装、t文字列のp文字列とのマッチング、パターン文字列の末尾からの' ''
3 '' ' とのマッチングには、badchar配列badchar []とgoodが必要です接尾辞配列goodsuffix []
4 各不一致の後、2つの基準の最大値に従ってp文字列を移動し、比較ポインタを末尾に移動します'' '
5 BadChar = BClist(p)
6 GoodSuffix = GSlist(p)
7 tlen、plen = (T)、lenの(P)でlen
8。 IF TLEN < PLEN:
9 リターン -1
10 。I、K = -PLEN ,. 1-PLENの1 #尾から、文字列pを比較し始めた
。11 移動= 0
12は 、一方 I <TLEN および K > =0:
13である IF T [I]が== P [K]:
14 。I、I-K = 1 ,. 1 K-
15 他:
16 BCmove-BadChar K = [ORD(T [I])] IF BadChar [ORD( T [I])] = - !1 他PLEN
。17 移動= MAX(GoodSuffix [K]は、BCmove) #1 スライド桁
18がある 。I、IがK + +移動-PLENを= 1-K ,. 1-PLEN
。19 IF K < = 0:
20であり、 リターン I + 1。
21は、 復帰 -1
22は
23である
24 DEF BClist(P):
25 '' ' 悪い文字ミスマッチ移動テーブル
26 右PのJ-BCの全列にj個のミスマッチ[T [J] ] ビット' ''
27 BC = [ - 1] * 128 #標準ACCIIテーブル128一般的に使用される文字を表示することができる
28 PLENは。= (P)でlen
29 のための I における範囲(PLEN):
30 BC [ORD(P [I])] = I #の使用ORD - CHR相互変換機能、直接間接添字文字として
31は 戻りBC
32
33である DEF GSList(P) :
34 '' ' 良いサフィックスメソッドを生成する不一致移動テーブル。iで不一致がある場合、3つのタイプに分けられます。それに応じて、文字数をスキップし、徐々に増加します
35 1.正常に一致した文字列によって形成されるサフィックスgs、 pストリングのxに等しいサブストリングがある場合、pストリングはi-x + 1; 36だけ 右にシフトされます。
条件1が満たされない場合は、pのプレフィックスで同じサフィックスgsを持つ最大のストリングを見つけ、サフィックスヘッダーをjに設定します。 、このステップはkmpに似ており、最大の等しい接頭辞と接尾辞を見つけ、p文字列を右にjビットシフトします;
37 3.条件1、2は当てはまりません。この比較のラウンドは失敗し、p文字列全体をp長さmだけ移動します'' '
38は、 PLENは= LEN(P)
39 GS = [PLEN] * PLENの #は、配列を初期化し、直接条件3の値に設定
40の GS [-PLEN 1] = 1つの #グッドサフィックスルールを単独で用いてもよく、に基づいています文字最適化のスキップにマッチした、最初に一致した場合、あなただけのp列移動する必要があります失敗します。
41はある ために私にレンジ(。-PLEN 1): #私が不一致
42 #の条件2、以下の要件私のpostfix最大値は、プレフィックスP列のプレフィックスに等しい
43 #をも最大を求めてほとんど、接尾辞の前に平等ではなく、異なるKMP KMPは接尾辞接頭辞ストリングの前に等しく、全体のpを求めて良いサフィックスアルゴリズムを求めているのに文字列の最大の等しいプレフィックスとサフィックスですが、プレフィックスとサフィックスの長さは制限されています
44 k = 0
45 j = i + 1
46 while j < plen:
47 if p [k] == p [j]:
48 K、K + 1 = J、J + 1。
49 他:
50 。J = J-K + 1
51は = K 0
52である IF!K = 0:
53れる GS [I] = 1- PLEN- K
54である #検索文字列P p [i + 1:]に等しい部分文字列はありますか、つまり条件1
55 substr = find_last(p [:plen-1]、p [i + 1 :])#find_last(t、p)関数はtを検索します文字列の最後のp文字列の開始位置。そうでない場合は、-1 56を 返し
ますsubstr!= -1の場合:
57 GS [i] = i-substr + 1 58 GSを返します