  
(1)文字列探索とは
文字列探索(string searching)とは,
ある文字列の中に,別の文字列が含まれているかどうか,
含まれている場合は,その位置を示すことです。
探索される側の文字列をテキスト(text),
探し出すための文字列をパターン(pattern)といいます。
(2)力まかせ法
パターンを1文字ずつずらしながら,
テキスト中の文字列と照合していく単純な方法を
力まかせ法(brute forth method),単純法,素朴法等と呼びます。


[プログラム例]
private int 力まかせ法(string 文字列,
string パターン)
{
int P1=0; int P2=0;
while(P1<文字列.Length &&
P2<パターン.Length)
{
if(文字列[P1] == パターン[P2]){
P1++; P2++;}
else { P1 = P1 - P2 +
1; P2
= 0; }
}
if(P2==パターン.Length) return(P1
- P2);
return -1;
}
private void button2_Click(object
sender,
System.EventArgs e)
{
string 文字列 = textBox1.Text;
string パターン = textBox2.Text;
label5.Text=力まかせ法(文字列,
パターン).ToString();
}
  
(3)KMP法
力まかせ法では,不一致文字があると,
パターンを移動して再びパターンの先頭から照合しています。
すなわち,それまでの照合結果が捨てられることになります。
そこで,
D. E. KnuthとV. R. Pratt,J. H. Morris が,ほぼ同時期に考案した
Knuth-Pratt-Morris 法,略してKMP法と呼ばれる方法では,
パターンの文字列の特徴を活かして
そこまでの照合結果を有効活用して探索します。
たとえば,以下のような探索を考えてみましょう。

(b)の段階では,6文字目が一致しませんが,
パターンの1,2文字目と4,5文字目が同じですから,
3文字目から照合を始めれば良いことになります。
このようにパターンの特徴を活かすことで,
照合する開始位置を省略することができます。
ただし,照合のたびに照合開始位置を決めるのは効率が悪いので,
最初にテーブルを作成します。
(a) 1文字目で不一致の場合

(b) 2文字目で不一致の場合
(c) 3文字目で不一致の場合
(d) 4字目で不一致の場合
(e) 5字目で不一致の場合
(f) 6字目で不一致の場合
■照合再開位置の設定
テーブルを作成するためには,パターン同士を1文字ずつずらしなら
以下のように,連続的に一致する文字数を
カウンすることで作成することができます。


[プログラム例]
private int KMP法(string 文字列, string
パターン)
{
int P1=1; int P2=0; int[] skip=new
int[256];
skip[P1]=0;
while (P1<パターン.Length)
{
if(パターン[P1]==パターン[P2])
skip[++P1]=++P2;
else if(P2==0) skip[++P1]=P2;
else P2=skip[P2];
}
P1=P2=0;
while(P1<文字列.Length &&
P2<パターン.Length)
{
if(文字列[P1] == パターン[P2]){
P1++; P2++;}
else if(P2 == 0) P1++;
else P2=skip[P2];
}
if(P2==パターン.Length) return(P1
- P2);
return -1;
}
private void button3_Click(object sender,
System.EventArgs e)
{
string 文字列 = textBox1.Text;
string パターン = textBox2.Text;
label5.Text=KMP法(文字列, パターン).ToString();
}
  
(4)BM法
この方法は,
R. S. BoyerとJ. S. Moore により提案したアルゴリズムで,
KMP法より簡単なアルゴリズムですが,効率のよい方法です。
Boyer-Moore 法,略してBM法と呼ばれます。
照合をパターンの末尾から行います。
一致しない文字を見つけた場合,
事前に用意した表により移動量を決めます。
例えば,以下のように4文字目で不一致のとき,
3文字ずらしても不一致になります。
これは,テキストの4文字目の”E”という文字が,
パターンに入っていないからです。
すなわち,パターンに入っていない文字を見つけたら,
文字数分をずらすことができます。
以下のように一致した場合は,ひとつ前の文字で比較します。

このとき2文字ずらしても不一致ですので,
3文字分ずらしてよいことになります。
以下のように,パターンの文字数分が一致すれば,成功です。

最初,以下のようなスキップ表を作成しておきます。
ここで,パターンの文字数をN,
パターンの最後に出現する位置の添え字をKとします。
テーブル
[プログラム例]
private int BM法(string 文字列, string
パターン)
{
int P1=0; int P2=0;
int txtLen = 文字列.Length;
int patLen = パターン.Length;
int[] skip=new int[char.MaxValue+1];
for(P1 =0; P1 <= char.MaxValue;
P1++) skip[P1]=patLen;
for(P1 =0; P1 <= patLen
- 1;P1++)
skip[パターン[P1]]=patLen - P1 -1;
// このとき,P1= patLen-1であることに注意
while(P1<文字列.Length)
{
P2=patLen - 1;
while(文字列[P1] == パターン[P2])
{
if (P2==0) return(P1);
P1--; P2--;
}
P1 += skip[文字列[P1]];
}
return -1;
}
private void button4_Click(object sender,
System.EventArgs e)
{
string 文字列 = textBox1.Text;
string パターン = textBox2.Text;
label5.Text=BM法(文字列, パターン).ToString();
}
  
1. 基本的なアルゴリズム
2. 基本的なデータ構造
3. 操作を伴うデータ構造
4. 探索
5. 再帰的アルゴリズム
6. ソート
7. 集合
8. 文字列処理
9. 色々なアルゴリズム

上のタイトルをクリックします
|