Python
 Computer >> コンピューター >  >> プログラミング >> Python

Pythonで文字列内の最長の反復部分文字列を見つける方法

Pythonでは、collectionsモジュールのdefaultdictを使うことで、入力文字列の各位置から始まるすべての部分文字列の出現回数を効率的に集計できます。

ポイントとなるのはgetsubsメソッドです。これはジェネレータ関数として実装されており、呼び出されるたびに指定位置から始まる部分文字列を、完全な文字列から1文字ずつ短くしたものまで順番にyield(生成)していきます。

コード例

from collections import defaultdict

def getsubs(loc, s):
    substr = s[loc:]
    i = -1
    while(substr):
        yield substr
        substr = s[loc:i]
        i -= 1

def longestRepetitiveSubstring(r):
    occ = defaultdict(int)
    # すべての部分文字列の出現回数を集計
    for i in range(len(r)):
        for sub in getsubs(i, r):
            occ[sub] += 1
    # 出現回数が2回未満の部分文字列を除外
    filtered = [k for k, v in occ.items() if v >= 2]
    if filtered:
        maxkey = max(filtered, key=len)  # 最も長い文字列を取得
        return maxkey
    else:
        raise ValueError("no repetitions of any substring of '%s' with 2 or more occurrences" % (r))

longestRepetitiveSubstring("hellopeople18654randomtexthellopeoplefromallaroundthe world")

処理の流れ

このプログラムは以下の手順で動作します。

  • 集計フェーズ: 文字列の先頭から順に各位置を起点として、そこから始まるすべての部分文字列を生成し、defaultdict(int)で出現回数をカウントします。
  • フィルタリング: 出現回数が2回以上の部分文字列だけをリストに残します。これにより、繰り返し登場する文字列のみが対象になります。
  • 最長判定: max(filtered, key=len)によって、条件を満たす中で最も長い部分文字列を取得します。
  • エラー処理: 繰り返しが一切存在しない場合は、ValueErrorを発生させて明確なメッセージを返します。

出力結果

上記のコードを実行すると、次のような出力が得られます。

'hellopeople'

この例では、入力文字列の中に「hellopeople」という部分が2回登場しているため、それが最長の反復部分文字列として検出されています。

注意点: このアプローチはシンプルで理解しやすい反面、すべての部分文字列を網羅的に調べるため、文字列が長くなると計算量がO(n²)以上に増大します。非常に長いテキストを扱う場合は、接尾辞配列(Suffix Array)や接尾辞木などのより高度なアルゴリズムを検討するとよいでしょう。

  1. Pythonで文字列を逆順にする方法|スライスとreversed()の使い方を解説

    Pythonでは、文字列スライスやrange演算子を活用することで、文字列を簡単に逆順(反転)にすることができます。この記事では、代表的な2つの方法をわかりやすく解説します。 方法1:スライス記法 [::-1] を使う(推奨・高速) 最もシンプルで一般的なのが、スライス記法を使う方法です。ステップに -1 を指定するだけで、文字列を後ろから前へ一文字ずつ取り出せます。 >>> Hello[::-1] olleH >>> Halloween[::-1] neewollaH スライスの仕組み 角括弧 [] の中には、コロン「:」で区切った3つの値を指定できます

  2. Pythonで部分文字列が文字列に含まれているか確認する方法(in演算子とfindメソッド)

    Pythonでは、ある文字列が別の文字列の部分文字列(サブストリング)として含まれているかどうかを簡単に確認できます。最も基本的な方法は、in 演算子を使うことです。in 演算子を使った判定方法in 演算子は、左辺の文字列が右辺の文字列に含まれている場合に True を、含まれていない場合に False を返します。以下はその使用例です。print(ello in hello world)実行結果:Trueこのように、ello は hello world の中に含まれているため、True が出力されます。find() メソッドで位置(インデックス)を取得する部分文字列が含まれているかどうかに加