숫자로만 이루어진 문자열 s가 주어졌다고 가정해 봅시다. 문자열 안에는 같은 숫자가 여러 번 반복해서 나타날 수 있습니다. 우리가 구해야 할 것은 각 숫자가 연속적으로 몇 번 나타났는지를 나타내는 (숫자, 개수) 형태의 쌍 목록입니다.
이 문제는 Python의 itertools 라이브러리에 포함된 groupby() 함수를 사용하면 아주 깔끔하게 해결할 수 있습니다. groupby()는 인접한 동일한 요소들을 하나의 그룹으로 묶어주는 이터레이터를 반환하며, 각 항목은 (키 값, 그룹 객체) 형태의 튜플로 구성됩니다. 따라서 각 그룹 객체에 담긴 요소의 개수를 세면 곧바로 원하는 결과를 얻을 수 있습니다.
문제 예시
예를 들어 입력이 s = "11522226551"이라면 출력은 다음과 같습니다.
[(1, 2), (5, 1), (2, 4), (6, 1), (5, 2), (1, 1)]
문자열 앞부분부터 차례대로 살펴보면, 1이 두 번 연속으로 나타나고, 그다음에는 5가 한 번, 이어서 2가 네 번 연속으로 나타나는 식입니다.
해결 절차
- 문자열 s에 대해
groupby()함수를 호출하여 이터레이터를 생성합니다. - 결과를 담을 빈 리스트를 준비합니다.
- 이터레이터에서 (숫자, 그룹 객체) 쌍을 하나씩 꺼내며, 각 그룹 객체를 리스트로 변환해 길이를 계산합니다.
- (숫자, 개수) 튜플을 결과 리스트에 추가합니다.
- 모든 그룹을 처리한 뒤 결과 리스트를 반환합니다.
구현 예제
아래 코드를 통해 실제 동작을 확인해 보겠습니다.
from itertools import groupby
def solve(s):
it = groupby(s)
ret = []
for digit, gp in it:
ret.append((int(digit), len(list(gp))))
return ret
s = "11522226551"
print(solve(s))입력
"11522226551"
출력
[(1, 2), (5, 1), (2, 4), (6, 1), (5, 2), (1, 1)]
코드 설명
groupby(s)는 문자열을 왼쪽부터 훑으면서 인접한 동일 문자들을 묶습니다. 각 단계에서 digit은 해당 그룹의 문자(예: '1', '5')이고, gp는 그룹에 속한 요소들을 담고 있는 이터레이터입니다. len(list(gp))를 호출하면 해당 그룹의 길이, 즉 연속 등장 횟수를 알 수 있으며, int(digit)로 문자형 숫자를 정수형으로 변환하여 최종 결과를 만듭니다.
참고로 groupby()는 인접한 동일 요소만 묶기 때문에, 정렬되지 않은 데이터에서 전체 등장 횟수를 세려면 먼저 정렬을 해야 합니다. 하지만 이 문제처럼 연속 구간 자체가 의미 있는 경우에는 정렬 없이 그대로 사용하는 것이 올바른 방법입니다.