문제 개요
세 개의 문자열이 주어졌을 때, 각각이 팬그램(Pangram), 리포그램(Lipogram), 팬그래매틱 리포그램(Pangrammatic Lipogram) 중 어느 것에 해당하는지 판별하는 문제입니다. 각 용어의 정의는 다음과 같습니다.
- 팬그램(Pangram): 알파벳의 모든 글자가 최소 한 번 이상 등장하는 문자열 또는 문장
- 리포그램(Lipogram): 알파벳 중 하나 이상의 글자가 아예 등장하지 않는 문자열 또는 문장
- 팬그래매틱 리포그램(Pangrammatic Lipogram): 알파벳 전체 26글자 중 딱 하나의 글자만 빠지고 나머지는 모두 등장하는 문자열 또는 문장
예를 들어 입력이 다음과 같다면,
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,
출력 결과는 다음과 같습니다.
이 문자열은 팬그램입니다 이 문자열은 팬그램이 아니며 리포그램일 수 있습니다 이 문자열은 팬그램입니다 이 문자열은 팬그래매틱 리포그램입니다
해결 접근 방법
핵심 아이디어는 간단합니다. 알파벳 a부터 z까지 각 글자가 문자열에 존재하는지 검사하고, 빠진 글자의 개수를 세면 됩니다. 빠진 글자 수에 따라 결과를 분류할 수 있습니다.
- 문자열의 모든 글자를 소문자로 변환합니다.
- 빠진 글자의 개수를 저장할 변수 i를 0으로 초기화합니다.
- 알파벳 소문자 a~z의 각 글자에 대해 다음을 확인합니다.
- 해당 글자가 입력 문자열에 없다면 i를 1 증가시킵니다.
- i가 0이면 "이 문자열은 팬그램입니다"를 출력합니다.
- i가 1이면 "이 문자열은 팬그래매틱 리포그램입니다"를 출력합니다.
- 그 외의 경우(글자가 2개 이상 누락)에는 "이 문자열은 팬그램이 아니며 리포그램일 수 있습니다"를 출력합니다.
- 최종 결과를 반환합니다.
파이썬 구현 예제
위 로직을 파이썬 코드로 구현하면 다음과 같습니다.
import string
def solve(input_string):
input_string = input_string.lower() # 소문자 변환 결과를 다시 저장
missing = 0
for character in string.ascii_lowercase:
if character not in input_string:
missing += 1
if missing == 0:
output = "이 문자열은 팬그램입니다"
elif missing == 1:
output = "이 문자열은 팬그래매틱 리포그램입니다"
else:
output = "이 문자열은 팬그램이 아니며 리포그램일 수 있습니다"
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"))
참고: 원본 코드에는 input_string.lower()의 반환값을 변수에 다시 할당하지 않아 대소문자 변환이 실제로 적용되지 않는 버그가 있었습니다. 위 코드에서는 이를 수정했으며, 가독성을 위해 find() 메서드 대신 in 연산자를 사용했습니다. 시간 복잡도는 O(n × 26)으로 문자열 길이에 비례하므로 매우 효율적입니다.
입력
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
출력
이 문자열은 팬그램입니다 이 문자열은 팬그램이 아니며 리포그램일 수 있습니다 이 문자열은 팬그램입니다 이 문자열은 팬그래매틱 리포그램입니다
정리
팬그램 계열 문제는 "알파벳 집합과 문자열의 차집합 크기"를 구하는 방식으로 손쉽게 해결할 수 있습니다. 빠진 글자가 0개면 팬그램, 정확히 1개면 팬그래매틱 리포그램, 2개 이상이면 일반적인 리포그램으로 분류됩니다. 이 접근법은 영어뿐 아니라 한글 자모 등 다른 문자 체계에도 동일하게 응용할 수 있습니다.