Pythonで文字列リストの最長共通プレフィックス(接頭辞)を求めるプログラム
小文字で構成された文字列のリストが与えられたとき、その中に共通して含まれる最長の共通プレフィックス(接頭辞)を見つける問題を考えてみましょう。
例えば、入力が ["antivirus", "anticlockwise", "antigravity"] の場合、すべての文字列に共通する先頭部分は "anti" なので、出力は "anti" となります。
解決のためのアプローチ
この問題は、以下の手順で解くことができます。
- まず、リスト
wordsをアルファベット順にソートします。これにより、辞書順で最も近い文字列同士が隣り合うため、比較が効率的になります。 - 共通プレフィックスを格納するための新しいリスト
prefixを用意し、フラグ変数flagを0で初期化します。 iを0からwords[0]の長さまで繰り返します。- 各反復で、
words[0][i]の文字をprefixに追加します。 - 次に、
words内のすべての文字列jについて、j[i]がprefixの末尾の文字と一致するかを確認します。- 一致しない場合は、
prefixの末尾の要素を削除し、flagを1に設定して、内側のループを抜けます。
- 一致しない場合は、
flagが1になっている場合は、外側のループも抜けます。
- 各反復で、
- 最後に、
prefixリスト内のすべての文字を連結した文字列を返します。
実装例
それでは、実際のコードを見てみましょう。
class Solution: def solve(self, words): words.sort() prefix = [] flag = 0 for i in range(len(words[0])): prefix.append(words[0][i]) for j in words: if j[i] != prefix[-1]: prefix.pop() flag = 1 break if flag == 1: break return ''.join(prefix) ob = Solution() words = ["antivirus", "anticlockwise", "antigravity"] print(ob.solve(words))
入力
["antivirus", "anticlockwise", "antigravity"]
出力
anti
コードのポイント
- ソートの役割: リストをソートすることで、最初の文字列と他の文字列の差分が最小限になり、早期に不一致を検出できます。
- フラグによる二重ループの制御: Pythonではラベル付きbreakが使えないため、
flag変数を利用して外側のループもまとめて終了させています。 - 計算量: 最悪の場合でも O(S) です。ここで S は全文字列の文字数の合計です。
このように、シンプルなループ処理とソートを組み合わせることで、複数の文字列から効率的に最長共通プレフィックスを抽出することができます。
-
【Python入門】2つの文字列から珍しい単語(ユニークな単語)を見つけるプログラムの作り方
はじめに この記事では、以下の問題文に対する解決方法を、実際のコード例とともにわかりやすく解説します。 問題文 2つの文字列が与えられたとき、その中から「珍しい単語」(どちらか一方の文字列にしか出現しない単語)をすべて抽出することを目標とします。両方の文字列に共通して含まれる単語は除外します。 解決のアプローチ ここでは辞書(dict)を使った出現回数のカウント方式を採用します。手順は次のとおりです。 空の辞書を用意する 各文字列をsplit()で単語ごとに分割する 各単語の出現回数を辞書に記録する 出現回数がちょうど1回の単語だけを結果として返す 実装例 # 珍しい単語を見つける関
-
Pythonで3つ以上の文字列から最長の共通部分文字列を見つける方法【動的計画法】
最長共通部分文字列(Longest Common Substring)を求めるアルゴリズムは、動的計画法(DP)を用いることで効率的に解けます。一般的なDP実装では、O(nm)の時間計算量で処理が可能です(n、mは比較対象となる文字列の長さ)。以下に、最長共通部分文字列アルゴリズムの実装例を示します。 実装例 def longest_common_substring(s1, s2): m = [[0] * (1 + len(s2)) for i in range(1 + len(s1))] lon