Pythonでアナグラム部分文字列検索プログラムを作成する方法
はじめに
この記事では、以下の問題文に対する解決策について学びます。
問題文 − テキストとパターンが与えられたとき、テキスト内に含まれるパターンおよびその順列(アナグラム)の出現位置をすべて出力します。
例えば、テキストが「TUTORIALSPOINT」、パターンが「TOR」であれば、「ROT」や「OTR」といった並べ替えも検索対象となります。
アルゴリズムの考え方
この問題は、スライディングウィンドウ(滑動窓)と文字カウント配列を組み合わせることで効率的に解くことができます。手順は以下のとおりです。
- パターン内の各文字の出現回数を、カウント配列 countP に記録します。
- テキストの先頭から、パターンと同じ長さのウィンドウ内の文字出現回数を、カウント配列 countTW に記録します。
- ウィンドウを1文字ずつ右へずらしながら、新しく入ってくる文字を countTW に加算し、外れていく文字を減算します。
- countP と countTW が一致したタイミングでは、その位置にパターンのアナグラムが存在することを意味します。
実装例
# 最大値
MAX = 300
# 2つのカウント配列を比較する関数
def compare(arr1, arr2):
for i in range(MAX):
if arr1[i] != arr2[i]:
return False
return True
# アナグラム検索を行う関数
def search(pat, txt):
M = len(pat)
N = len(txt)
# countP: パターンの文字出現数
# countTW: テキストの現在のウィンドウ内の文字出現数
countP = [0] * MAX
countTW = [0] * MAX
for i in range(M):
countP[ord(pat[i])] += 1
countTW[ord(txt[i])] += 1
# ウィンドウを1文字ずつずらしながら走査
for i in range(M, N):
# 現在のウィンドウとパターンの文字数を比較
if compare(countP, countTW):
print("見つかったインデックス:", (i - M))
# ウィンドウに新しい文字を追加
countTW[ord(txt[i])] += 1
# ウィンドウから先頭の文字を削除
countTW[ord(txt[i - M])] -= 1
# 最後のウィンドウをチェック
if compare(countP, countTW):
print("見つかったインデックス:", (N - M))
# メイン処理
txt = "TUTORIALSPOINT"
pat = "TOR"
search(pat, txt)
出力
見つかったインデックス: 2

すべての変数はローカルスコープで宣言されており、その参照関係は上の図のとおりです。
まとめ
この記事では、文字カウント配列とスライディングウィンドウを活用し、テキスト内に含まれるパターンとそのアナグラム(順列)をすべて検出するPythonプログラムの作成方法について学びました。この手法を用いれば、すべての並べ替えを生成して総当たりで探すよりもはるかに効率的にアナグラム検索が行えます。
-
Pythonで選択ソートを実装する方法|仕組みとサンプルコードをわかりやすく解説
この記事では、選択ソート(Selection Sort)の基本的な仕組みと、Python 3.x(およびそれ以前のバージョン)での実装方法について解説します。 選択ソートとは 選択ソートは、ソートされていない部分から最小の要素を繰り返し見つけ出し、先頭側へ移動させることで配列全体を整列していくアルゴリズムです。処理の過程で、対象の配列は次の2つの部分配列に分けられます。 すでにソートが完了している部分配列 まだソートされていない部分配列 選択ソートの各イテレーションでは、未ソートの部分配列から最小要素を取り出し、ソート済みの部分配列の末尾に追加していきます。 アルゴリズムの動作イメー
-
Pythonで学ぶ挿入ソート(Insertion Sort)の仕組みと実装方法
この記事では、Python 3.xにおける挿入ソート(Insertion Sort)の基本的な考え方と、実際のコードによる実装方法をわかりやすく解説します。 挿入ソートのアルゴリズム 挿入ソートは、配列を「整列済みの部分」と「未整列の部分」に分け、未整列の要素を一つずつ取り出して、整列済み部分の正しい位置に挿入していくシンプルなソート手法です。処理の手順は以下の通りです。 1. 各反復ごとに整列済みの配列を少しずつ拡大しながら、入力要素を走査する。 2. 現在の要素(キー)を、整列済み配列内の最大値と比較する。 3. キーがその最大値より大きければ、要素はそのままの位置に置かれ、 次の要