영숫자(alphanumeric)로 이루어진 문자열 s가 하나 주어졌다고 가정해 보겠습니다. 이 문자열을 다음 조건에 따라 정렬해야 합니다.
- 모든 소문자는 대문자보다 앞에 위치하며, 소문자끼리는 알파벳 순으로 정렬됩니다.
- 모든 대문자는 숫자보다 앞에 위치하며, 대문자끼리는 알파벳 순으로 정렬됩니다.
- 홀수 숫자는 짝수 숫자보다 앞에 위치하며, 각 그룹 내에서는 오름차순으로 정렬됩니다.
예를 들어 입력이 s = "HeLlo1234"라면, 출력은 eloHL1324가 됩니다.
해결 접근 방식
이 문제는 각 문자에 우선순위 코드(priority code)를 부여한 뒤, 해당 코드를 정렬 키로 사용하여 해결할 수 있습니다. 단계별로 살펴보겠습니다.
- 함수
f()를 정의합니다. 이 함수는 문자c를 인자로 받아 정렬 기준이 되는 값을 계산합니다. code를 0으로 초기화합니다.c가 대문자라면code를 10³으로 설정합니다.c가 숫자라면code를 10⁶으로 설정하고, 추가로c의 아스키(ASCII) 코드가 짝수라면code를 10⁹으로 설정합니다.code와c의 아스키 코드 값을 더하여 반환합니다.
이렇게 하면 소문자는 가장 작은 값(0 + 아스키 코드), 대문자는 중간 값(1000 + 아스키 코드), 홀수는 그 다음 값(1000000 + 아스키 코드), 짝수는 가장 큰 값(1000000000 + 아스키 코드)을 갖게 됩니다. 따라서 이 값을 기준으로 정렬하면 자연스럽게 소문자 → 대문자 → 홀수 → 짝수 순서가 완성됩니다.
- 메인 로직에서는 문자열
s의 각 문자를f()함수의 반환값을 기준으로 정렬한 리스트l을 생성합니다. - 리스트
l의 문자들을 하나로 연결(join)하여 최종 결과를 반환합니다.
구현 예제
아래 구현을 통해 더 잘 이해해 보겠습니다.
def f(c):
code = 0
if c.isupper():
code = 10 ** 3
elif c.isdigit():
code = 10 ** 6
if ord(c) % 2 == 0:
code = 10 ** 9
return code + ord(c)
def solve(s):
l = sorted(s, key=lambda c: f(c))
return ''.join(l)
s = "HeLlo1234"
print(solve(s))입력
"HeLlo1234"
출력
eloHL1324