Pythonで文字列がパングラマティック・リポグラムかどうかを判定する方法
今回は、複数の文字列が与えられたとき、それぞれが「パングラム」「リポグラム」「パングラマティック・リポグラム」のどれに該当するかを判定する問題を扱います。まずは各用語の意味を確認しておきましょう。
用語の定義
- パングラム(Pangram): アルファベット26文字すべてが少なくとも1回は登場する文や文字列。
- リポグラム(Lipogram): アルファベットのうち1つ以上の文字が登場しない文や文字列。
- パングラマティック・リポグラム(Pangrammatic Lipogram): アルファベット26文字のうち、ちょうど1文字だけ欠けている文や文字列。
例えば、次のような入力が与えられたとします。
pack my box with five dozen liquor jugs to stay in this mortal world or by my own hand go to oblivion, that is my conundrum. the quick brown fox jumps over a lazy dog waltz, nymph, for quick jigs ve bud,
この場合の出力は以下のようになります。
The String is a Pangram The String isn't a Pangram but might be a Lipogram The String is a Pangram The String is a Pangrammatic Lipogram
解き方のアプローチ
この問題は、次の手順で解決できます。
- 文字列内のすべての英字を小文字に変換します。
- カウンター変数
iを 0 で初期化します。 - アルファベットの各文字について、入力文字列に含まれていない場合は
iを 1 増やします。 - 最終的な
iの値に応じて結果を判定します。i == 0→ すべての文字が含まれるため「パングラム」i == 1→ 1文字だけ欠けているため「パングラマティック・リポグラム」- それ以外 → 「パングラムではないが、リポグラムの可能性がある」
実装例
それでは、実際のPythonコードを見てみましょう。
import string
def solve(input_string):
input_string = input_string.lower()
i = 0
for character in string.ascii_lowercase:
if input_string.find(character) < 0:
i += 1
if i == 0:
output = "The String is a Pangram"
elif i == 1:
output = "The String is a Pangrammatic Lipogram"
else:
output = "The String isn't a Pangram but might be a Lipogram"
return output
print(solve("pack my box with five dozen liquor jugs"))
print(solve("to stay in this mortal world or by my own hand go to oblivion, that is my conundrum."))
print(solve("the quick brown fox jumps over a lazy dog"))
print(solve("waltz, nymph, for quick jigs ve bud"))
入力
pack my box with five dozen liquor jugs to stay in this mortal world or by my own hand go to oblivion, that is my conundrum. the quick brown fox jumps over a lazy dog waltz, nymph, for quick jigs ve bud
出力
The String is a Pangram The String isn't a Pangram but might be a Lipogram The String is a Pangram The String is a Pangrammatic Lipogram
コードのポイント
string.ascii_lowercaseは'abcdefghijklmnopqrstuvwxyz'という小文字アルファベット一覧を返す定数です。str.find()は指定した文字が見つかった場合はその位置を、見つからなかった場合は-1を返します。この性質を利用して、含まれていない文字を数えています。- なお、元のコードでは
input_string.lower()の戻り値を変数に再代入していなかったため、大文字を含む文字列では正しく判定できません。input_string = input_string.lower()のように代入することで、大文字・小文字を問わず正確に判定できるようになります。
このように、欠けているアルファベットの文字数を数えるだけで、パングラムかリポグラムか、あるいはその中間的な性質を持つパングラマティック・リポグラムかを簡単に判別できます。計算量は O(n × 26) となり、非常に効率的な手法です。
-
Pythonで文字列がパングラムかどうかを判定するプログラムの作成方法
本記事では、与えられた文字列がパングラムであるかどうかを判定するPythonプログラムの解法とアプローチについて詳しく解説します。 問題の概要 文字列入力が与えられたとき、その文字列がパングラムであるかどうかを判定するPythonプログラムを作成します。 パングラムとは? パングラムとは、英語のアルファベット26文字すべてを少なくとも1回ずつ含む文章や一連の単語のことです。有名な例として「The quick brown fox jumps over the lazy dog」があります。 解法のアプローチ この問題は、以下の手順で解くことができます。 アルファベット全体を表す基準となる文字列
-
Pythonで文字列が英数字のみかどうかを判定する方法【isalnum()と正規表現】
Pythonでは、文字列が英数字(アルファベットと数字)のみで構成されているかどうかを簡単に判定できます。主な方法は2つあります。文字列クラスに組み込まれている isalnum() メソッドを使う方法と、正規表現を使う方法です。 isalnum()メソッドを使う方法 Pythonの文字列クラスには isalnum() というメソッドが用意されています。このメソッドを文字列に対して呼び出すと、文字列が英数字のみで構成されている場合に True を、記号などが含まれる場合には False を返します。 >>> 123abc.isalnum() True >>>