회문(Palindrome)이란?
회문(回文, Palindrome)은 왼쪽에서 오른쪽으로 읽어도, 오른쪽에서 왼쪽으로 읽어도 똑같은 문자열을 의미합니다. 즉, 문자열을 거꾸로 뒤집었을 때 원래 문자열과 동일하다면 그 문자열이 바로 회문입니다.
예를 들어 civic, madam은 회문입니다. 반면 cat은 회문이 아닙니다. cat을 뒤집으면 tac이 되는데, 이는 원래 문자열과 다르기 때문입니다.
이번 글에서는 입력받은 문자열이 회문인지 아닌지를 판별하는 파이썬 프로그램을 두 가지 방법으로 작성해 보겠습니다.
방법 1 – 문자열을 뒤집어서 비교하기
- 이 방법의 핵심은 문자열을 뒤집는 것입니다.
- 문자열을 뒤집는 방법은 여러 가지가 있지만, 여기서는 가장 간단한 슬라이싱(Slicing) 기법을 사용합니다. ''.join(reversed()) 조합을 활용할 수도 있습니다.
- 뒤집은 문자열과 원본 문자열을 비교합니다.
- 두 문자열이 완전히 같으면 True, 하나라도 다르면 False를 반환합니다.
예제 코드
def isPalindrome(s):
rev = s[::-1]
if rev == s:
return True
return False
print('문자열을 입력하세요')
st = input()
print(isPalindrome(st))실행 결과
문자열을 입력하세요
madam
Trues[::-1]은 문자열 전체를 역순으로 잘라내는 파이썬 특유의 문법으로, 별도의 반복문 없이 한 줄로 문자열을 뒤집을 수 있다는 장점이 있습니다.
방법 2 – 뒤집지 않고 양끝부터 비교하기
이 방법의 핵심 아이디어는 문자열의 첫 번째 문자와 마지막 문자를 계속 비교하다가, 서로 다른 문자가 나타나는 순간 회문이 아니라고 판단하는 것입니다.
동작 원리 예시
'madam'의 경우: 첫 글자 m과 마지막 글자 m이 같으므로 통과하고, 두 번째 a와 뒤에서 두 번째 a를 비교해도 같습니다. 마지막에는 가운데 글자 하나만 남게 되므로 이 문자열은 회문입니다.
'reader'의 경우: 앞부분 몇 글자는 서로 일치하지만, 세 번째 문자와 뒤에서 세 번째 문자를 비교하는 시점에 서로 달라지므로 회문이 아닙니다.
이 로직은 재귀(recursion) 또는 두 개의 포인터(two pointers)로 구현할 수 있으며, 여기서는 투 포인터 방식을 사용하겠습니다. start 포인터는 인덱스 0에서, end 포인터는 마지막 인덱스에서 시작해 두 문자가 같으면 start는 +1, end는 −1씩 이동하며 안쪽으로 좁혀갑니다.
- False를 반환하는 경우: 어떤 시점에서든 두 포인터가 가리키는 문자가 다르면 더 이상 검사할 필요 없이 즉시 False를 반환합니다.
- True를 반환하는 경우: 두 포인터가 만나거나(start == end, 검사할 문자가 하나만 남은 상태) start가 end를 넘어서면(start > end, 모든 문자 검사 완료) 회문이므로 True를 반환합니다.
예제 코드
def isPalindrome(s):
start = 0
end = len(s) - 1
while start < end:
if s[start] != s[end]:
return False
start += 1
end -= 1
return True
print('문자열을 입력하세요')
st = input()
print(isPalindrome(st))실행 결과
문자열을 입력하세요
reader
False
문자열을 입력하세요
madam
True이 방법은 최악의 경우에도 문자열 길이의 절반만큼만 비교하면 되고, 불일치가 발견되는 즉시 종료되므로 실질적으로 매우 효율적입니다. 또한 추가 메모리 없이 제자리(in-place)에서 검사할 수 있어 공간 복잡도 면에서도 유리합니다.
보너스: 숫자가 회문인지 확인하기
문자열뿐만 아니라 숫자도 회문 여부를 확인할 수 있습니다. 숫자를 str() 함수로 문자열로 변환한 뒤 같은 로직을 적용하면 됩니다.
def isNumPalindrome(n):
s = str(n)
return s == s[::-1]
print(isNumPalindrome(12321)) # True
print(isNumPalindrome(12345)) # False마무리
정리하면, 파이썬에서 회문을 판별하는 가장 간결한 방법은 슬라이싱(s[::-1])을 이용한 뒤집기 비교이며, 메모리 사용을 최소화하거나 알고리즘 학습이 목적이라면 투 포인터 방식이 좋은 선택입니다. 상황에 맞는 방법을 골라 활용해 보세요.