Pythonで文字列内の重複しない部分文字列の個数を求めるプログラム
問題の概要
ある文字列 s が与えられたとします。ここでの課題は、s から取り出せるすべての部分文字列のうち、重複しないもの(ユニークなもの)だけを抽出し、その総数を出力することです。
たとえば、入力が s = 'prrstvt' の場合、出力は 26 になります。
このとき得られる重複しない部分文字列は、以下の26種類です。
'pr'、'rrs'、'st'、'rr'、'tv'、'rstv'、'stvt'、'prrstv'、'prrstvt'、'rrstvt'、's'、'prrst'、'stv'、'rrstv'、'rst'、'v'、'tvt'、'rstvt'、'r'、'rs'、'vt'、't'、'prr'、'p'、'rrst'、'prrs'
解法の考え方
この問題は、「各位置で終わる部分文字列」を順番に生成していくことで効率的に解けます。具体的には、次の手順に従って処理を進めます。
- まず、結果を記録するための辞書
visitedを新しく用意します。 - 文字列
sの各インデックスindと、その位置にある文字letについて、以下の処理を繰り返します。- 新しい集合
tempを作成します。 visitedにind - 1が存在する場合、直前の位置で終わるすべての部分文字列has_letに対して、末尾にletを連結した文字列(has_let + let)をtempに追加します。- さらに、1文字のみの部分文字列として
letそのものもtempに追加します。 tempをvisited[ind]として保存します。
- 新しい集合
- すべての部分文字列を統合するための新しい集合
resを用意します。 visitedに格納された各集合の要素をすべてresに追加します。- 最後に
resのサイズ、つまり重複しない部分文字列の個数を返します。
集合(set)を利用することで、同一の部分文字列が自動的に除外されるため、重複チェックのロジックを明示的に書く必要がないのが大きなポイントです。
実装例
それでは、実際のPythonコードを見てみましょう。
def solve(s):
visited = dict()
for ind, let in enumerate(s):
temp = set()
if ind-1 in visited:
for has_let in visited[ind-1]:
temp.add(has_let+let)
temp.add(let)
visited[ind] = temp
res = set()
for sets in visited:
res.update(visited[sets])
return len(res)
print(solve('prrstvt'))
入力
'prrstvt'
出力
26
計算量について
長さ n の文字列の場合、部分文字列は最大でも n(n+1)/2 個であり、それぞれの連結操作に最大で O(n) かかるため、全体の時間計算量・空間計算量は O(n³) 程度になります。短めの文字列であれば十分実用的ですが、非常に長い文字列を扱うケースでは、接尾辞配列や接尾辞木といったより高度なデータ構造の活用を検討するとよいでしょう。
-
Pythonで文字列・数値が回文(パリンドローム)かどうかを判定する方法【スライス活用】
本記事では、入力された文字列や数値が回文(パリンドローム)であるかどうかを判定するPythonプログラムの解決策とアプローチについて解説します。 問題の概要 文字列が入力として与えられたとき、それが回文であるかどうかを判定するPython関数を作成する必要があります。 回文とは、文字列を逆から読んでも元の文字列と完全に一致するものを指します。たとえば「78287」や「しんぶんし」などが代表的な例です。 解決のアプローチ 回文判定は、主に以下の2つの方法で実現できます。 スライスによる文字列の反転 負のインデックスを使った比較 本記事では、このうちスライスを使った文字列の反転方法を中心に
-
Pythonで数値の2進表現における最長の連続する1の長さを求めるプログラム
整数が与えられたとき、その2進表現(バイナリ表現)の中で最も長く連続する「1」の長さを求めるPythonプログラムを紹介します。 例 入力: n = 15 出力: 4 15 の2進表現は 1111 です。 この場合、「1」が4つ連続しているため、答えは4となります。 アルゴリズム 数値を入力として受け取ります。 カウンタ変数 c を 0 で初期化します。 n が 0 になるまでの反復回数を数えます。 ビット演算 n & (n << 1) を行うことで、1の連続列の長さが毎回1つずつ短くなっていきます。 アルゴリズムのポイント この手法の鍵となるのは n &