質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.46%
アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

コードレビュー

コードレビューは、ソフトウェア開発の一工程で、 ソースコードの検査を行い、開発工程で見過ごされた誤りを検出する事で、 ソフトウェア品質を高めるためのものです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

1385閲覧

BM法(Python)のテキストとパターンが一致しない場合の条件分岐の意味について教えてください

fu_3823

総合スコア81

アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

コードレビュー

コードレビューは、ソフトウェア開発の一工程で、 ソースコードの検査を行い、開発工程で見過ごされた誤りを検出する事で、 ソフトウェア品質を高めるためのものです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

1クリップ

投稿2021/06/01 16:52

編集2021/06/02 03:01

BM法のサンプルコードを参考にしながら、アルゴリズムの意味とコードの動きを照らし合わせています。アルゴリズムの意味は理解できたつもりでいます。ただ、以下のコードの#####をつけた条件分岐のブロックを、アルゴリズムに照らした場合、どう解釈していいのかわかりません。
この#####の部分は、テキストとパターンが一致しない時の処理ですが、
skip[ord(txt[pt])] > len(pat) - pp:
↑この箇所は、どのような状況を評価できることになるのでしょうか。

この条件分岐の式の意味がわからないので、
pt += skip[ord(txt[pt])] として、
スキップテーブルの値分だけテキストの着目箇所を進める場合と、
pt += len(pat) - pp と
する場合の違いがわかりません。

Pyhton

1def bm_match(txt: str, pat:str) -> int: 2 skip = [None] * 256 3 for pt in range(256): 4 skip[pt] = len(pat) 5 for pt in range(len(pat)): 6 skip[ord(pat[pt])] = len(pat) - pt - 1 7 8 while pt < len(txt): 9 pp = len(pat) - 1 10 while txt[pt] == pat[pp]: 11 if pp == 0: 12 return pt 13 pt -= 1 14 pp -= 1 15 16 ##### 17 if skip[ord(txt[pt])] > len(pat) - pp: 18 pt += skip[ord(txt[pt])] 19 else: 20 pt += len(pat) - pp 21 22 return -1 23 24 25 26if __name__ == "__main__": 27 txt = "abcxdezaabababac" 28 pat = "abab" 29 30 print(txt) 31 print(pat) 32 print(bm_match(txt, pat))

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

大きい方だけずらしましょう、という意味でしょう。

python

1def bm_match(txt: str, pat:str) -> int: 2 skip = [None] * 256 3 for pt in range(256): 4 skip[pt] = len(pat) 5 for pt in range(len(pat)): 6 skip[ord(pat[pt])] = len(pat) - pt - 1 7 while pt < len(txt): 8 pp = len(pat) - 1 9 while txt[pt] == pat[pp]: 10 if pp == 0: 11 return pt 12 pt -= 1 13 pp -= 1 14 ##### 15 print(f'現在位置:{txt[pt:]}') 16 print(f'skip[ord(txt[pt])]:{skip[ord(txt[pt])]}, len(pat) - pp:{len(pat) - pp}]') 17 if skip[ord(txt[pt])] > len(pat) - pp: 18 print(f'select skip[ord(txt[pt])]:{skip[ord(txt[pt])]}') 19 pt += skip[ord(txt[pt])] 20 else: 21 print(f'select len(pat) - pp:{len(pat) - pp}]') 22 pt += len(pat) - pp 23 return -1 24 25txt = "abcxdezaabababac" 26pat = "abab" 27print(bm_match(txt, pat))

実行結果は以下です。

python

1>>> print(bm_match(txt, pat)) 2現在位置:xdezaabababac 3skip[ord(txt[pt])]:4, len(pat) - pp:1] 4select skip[ord(txt[pt])]:4 5現在位置:aabababac 6skip[ord(txt[pt])]:1, len(pat) - pp:1] 7select len(pat) - pp:1] 8現在位置:abababac 9skip[ord(txt[pt])]:1, len(pat) - pp:1] 10select len(pat) - pp:1] 11現在位置:aabababac 12skip[ord(txt[pt])]:1, len(pat) - pp:3] 13select len(pat) - pp:3] 14現在位置:ababac 15skip[ord(txt[pt])]:1, len(pat) - pp:1] 16select len(pat) - pp:1] 178

投稿2021/06/02 00:15

ppaul

総合スコア24666

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fu_3823

2021/06/02 07:09

ありがとうございます。「大きい方だけずらす」ことを改めて指摘され、トレースを繰り返してやっと以下の内容と、サンプルコードの関係性を理解できました。 ・不一致になった場合、skip表にある値分だけカーソルを進める。 ・ただし、ずらした位置が比較開始位置より手前だった場合、比較開始位置の1文字後に カーソルを進める。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問