이번 튜토리얼에서는 Python에서 문자열의 앞쪽 절반과 뒤쪽 절반이 서로 동일한 문자 집합을 가지고 있는지 확인하는 방법을 알아보겠습니다. 여기서 중요한 조건은 두 절반에 포함된 문자들의 빈도(개수)까지 정확히 일치해야 한다는 점입니다.
만약 문자열의 길이가 홀수라면, 가운데 문자는 무시하고 나머지 문자들만 비교하면 됩니다. 그럼 단계별로 프로그램을 작성해 보겠습니다.
알고리즘
전체 로직은 다음 순서로 진행됩니다.
1. 문자열을 초기화한다.
2. 빈 딕셔너리 변수 alphabets를 초기화한다.
3. mid 변수를 문자열 길이 // 2로 초기화한다.
4. 첫 번째 절반(mid까지)을 순회하는 반복문을 작성한다.
4.1. 해당 문자가 딕셔너리에 없다면 alphabets[char] = 1로 초기화한다.
4.2. 이미 존재한다면 개수를 1 증가시킨다.
5. 두 번째 절반(mid부터 끝까지)을 순회하는 반복문을 작성한다.
5.1. 해당 문자가 딕셔너리에 있는지 확인한다.
5.1.1. 있다면 그 문자의 개수를 1 감소시킨다.
6. 딕셔너리 alphabets 전체를 순회한다.
6.1. 값이 0이 아닌 항목이 하나라도 있으면 "No!"를 출력한다.
6.2. 모두 0이라면 "Yes!"를 출력한다.핵심 아이디어는 간단합니다. 앞쪽 절반에서는 문자 개수를 증가시키고, 뒤쪽 절반에서는 개수를 감소시킵니다. 최종적으로 모든 값이 0이라면 두 절반의 문자 집합과 빈도가 완벽하게 일치하는 것입니다.
예제 코드
위 알고리즘을 실제 코드로 구현해 보겠습니다.
## 문자열 초기화
string = "aabccbaa"
## 빈 딕셔너리 초기화
alphabets = {}
## mid 변수 초기화
mid = len(string) // 2
## 앞쪽 절반의 문자 빈도를 세는 반복문
for i in range(mid):
## 딕셔너리에 없으면 1로 설정
if not alphabets.get(string[i], 0):
alphabets[string[i]] = 1
else:
## 이미 존재하면 개수 1 증가
alphabets[string[i]] += 1
## 뒤쪽 절반의 문자가 딕셔너리에 있으면 개수를 1 감소시키는 반복문
for i in range(len(string) - 1, mid - 1, -1):
## 뒤쪽 절반에 해당 문자가 있는지 확인
if alphabets.get(string[i], 0):
## 존재하면 개수 1 감소
alphabets[string[i]] -= 1
## 결과 판단용 플래그 변수
flag = 1
## 감소 후 모든 값이 0인지 검사하는 반복문
for i in alphabets.values():
## 0이 아닌 값이 있으면 No! 출력 후 종료
if i != 0:
print("No!")
flag = 0
break
## 플래그가 그대로 1이면 Yes!
if flag == 1:
print("Yes!")출력 결과
위 프로그램을 실행하면 다음과 같은 결과를 얻을 수 있습니다.
Yes!
문자열 "aabccbaa"의 경우 앞쪽 절반은 aabc, 뒤쪽 절반은 cbaa입니다. 두 절반 모두 {a: 2, b: 1, c: 1}로 문자 집합과 빈도가 일치하므로 Yes!가 출력됩니다.
더 간단한 대안: collections.Counter 활용
딕셔너리를 직접 조작하는 대신, 파이썬 표준 라이브러리의 Counter를 사용하면 코드를 훨씬 간결하게 만들 수 있습니다.
from collections import Counter
string = "aabccbaa"
mid = len(string) // 2
first_half = Counter(string[:mid])
second_half = Counter(string[mid:])
print("Yes!" if first_half == second_half else "No!")Counter 객체끼리 비교하면 내부적으로 모든 문자의 빈도를 자동으로 검사해 주기 때문에, 직접 반복문을 작성하는 것보다 가독성과 유지보수성이 크게 향상됩니다.
마무리
이번 글에서는 문자열의 양쪽 절반이 동일한 문자 집합과 빈도를 갖는지 확인하는 두 가지 방법을 살펴보았습니다. 기본 딕셔너리를 이용한 방식은 알고리즘의 동작 원리를 이해하는 데 도움이 되고, Counter를 활용한 방식은 실무에서 더 효율적입니다. 튜토리얼에 대해 궁금한 점이 있다면 댓글로 남겨주세요!