Pythonでのワイルドカードマッチング:動的計画法を使った実装方法
入力文字列 s と、もう一つの入力文字列 p があるとします。s が対象となる文字列で、p はパターンです。この記事では、文字列がパターンに一致するかどうかを判定するメソッドを Python で実装します。具体的には、「?」や「*」といったワイルドカード文字をサポートする正規表現マッチングを実装していきます。
ワイルドカードのルール
- 「?」(クエスチョンマーク):任意の1文字に一致します。
- 「*」(アスタリスク):0個以上の任意の文字列に一致します。
例えば、s = "aa"、p = "a?" という入力の場合、結果は True になります。同じ入力文字列に対して、パターンが "?*" の場合も True となります。
解法のアプローチ:動的計画法
この問題は動的計画法(DP)を使うことで効率的に解けます。以下の手順に従います。
ssを s の長さ、psを p の長さとします。- (ss + 1) × (ps + 1) のサイズの2次元配列
dpを作成し、すべて False で初期化します。 - s と p の先頭に空白を1文字追加します。これにより、空文字列の場合も含めてインデックスの扱いが簡単になります。
- i を 1 から ps まで繰り返します。p[i] が「*」の場合、dp[0][i] = dp[0][i - 1] とします(空文字列に対しても「*」は連続してマッチできるためです)。
- i を 1 から ss まで、j を 1 から ps まで二重ループで繰り返します。
- s[i] と p[j] が一致する、または p[j] が「?」の場合:dp[i][j] = dp[i - 1][j - 1]
- それ以外で p[j] が「*」の場合:dp[i][j] = dp[i - 1][j] と dp[i][j - 1] のいずれか(どちらか一方でも True なら True)
- 最後に dp[ss][ps] を返します。これが全体のマッチング結果になります。
Pythonでの実装例
以下のコードを見ると、より理解が深まるでしょう。
class Solution(object):
def isMatch(self, s, p):
sl = len(s)
pl = len(p)
dp = [[False for i in range(pl+1)] for j in range(sl+1)]
s = " "+s
p = " "+p
dp[0][0]=True
for i in range(1,pl+1):
if p[i] == '*':
dp[0][i] = dp[0][i-1]
for i in range(1,sl+1):
for j in range(1,pl+1):
if s[i] == p[j] or p[j] == '?':
dp[i][j] = dp[i-1][j-1]
elif p[j]=='*':
dp[i][j] = max(dp[i-1][j],dp[i][j-1])
return dp[sl][pl]
ob = Solution()
print(ob.isMatch("aa", "a?"))
print(ob.isMatch("aaaaaa", "a*"))
入力
"aa", "a?" "aaaaaa", "a*"
出力
True True
まとめ
このアルゴリズムの計算量は、時間・空間ともに O(ss × ps) です。「*」が「直前の文字を消費しない(dp[i][j-1])」のか「現在の文字を消費する(dp[i-1][j])」のかという2通りのケースを考慮することで、単純な貪欲法では対応が難しいバックトラックの問題を、動的計画法によって効率よく解決できます。
-
【初心者向け】Pythonのissuperset()メソッドの使い方をわかりやすく解説
はじめにこの記事では、Pythonのissuperset()メソッドについて、基本的な仕組みから実際のコード例まで詳しく解説します。issuperset()は、セット(集合)に対して使用できるメソッドで、引数として渡されたセットのすべての要素が、呼び出し元のセットに含まれているかどうかを判定します。呼び出し元のセットBが、引数のセットAのすべての要素を含んでいる場合 → True を返すセットAの要素がすべてBに含まれていない場合 → False を返すつまり、「BがAの上位集合(スーパーセット)であるかどうか」を判定するためのメソッドです。基本構文B.issuperset(A)この式は、Bが
-
PythonとOpenCVで実現するテンプレートマッチングの基本とマルチスケール対応
テンプレートマッチングとは、実際の画像の中から、あらかじめ用意した小さな画像(テンプレート)と一致する部分を探し出す技術です。基本的にはパターンマッチングの一種であり、物体検出や顔認識など、さまざまなコンピュータビジョンのタスクの基礎となる手法です。PythonではOpenCVモジュールを使うことで、このマッチング処理を簡単に実装できます。本記事では、OpenCVのテンプレートマッチング機能を使った具体的な方法を解説します。OpenCVのインストールOpenCVの機能を利用するには、まずpipでライブラリをインストールします。sudo pip3 install opencv-python閾値(