문제7 - 이상한 문자 만들기 (Python)

 

프로그래머스

SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

문자열에 포함된 각 단어의 인덱스를 기준으로 짝수 번째는 대문자, 홀수 번째는 소문자로 변환하는 문제입니다. 전체 문자열의 인덱스가 아닌 '단어 단위'의 인덱스 관리가 핵심입니다.


1. 나의 풀이 (Modular Approach)

def solution(s: str) -> str:
    # 문자열과 동일한 길이의 공백 리스트 생성
    answer = [' '] * len(s)
    
    # 단어별 인덱스를 관리할 카운트 변수
    cnt = 0
    
    for i in range(len(s)):
        # 알파벳인 경우에만 대/소문자 변환 로직 적용
        if s[i].isalpha():
            answer[i] = s[i].lower() if cnt % 2 != 0 else s[i].upper()
            cnt += 1
        # 공백(또는 특수문자)을 만나면 단어가 끝난 것으로 간주하여 카운트 초기화
        else:
            cnt = 0
            
    return ''.join(answer)

2.  오늘 배운 점 및 복기 노트

split() 함수의 기본 동작 방식과 예외 케이스
가장 처음 시도했던 s.split() 방식이 실패한 이유는 해당 함수의 기본 동작 특성 때문입니다. split()은 공백이 몇 개든 상관없이 하나의 구분자로 취급하여 제거합니다. 하지만 이 문제의 제한 사항에는 "하나 이상의 공백문자"가 포함될 수 있다고 명시되어 있습니다. 원본 문자열의 공백 개수를 그대로 유지해야 하는 문제에서는 split() 후 다시 합치는 방식이 위험할 수 있음을 확인했습니다.

상태 관리 변수(cnt)의 효용성
문자열 전체를 순회하면서도 특정 조건(공백)에 따라 독립적인 인덱스가 필요할 때는 별도의 카운트 변수를 사용하는 것이 효율적입니다. for i in range(len(s))는 전체 물리적 위치를 추적하고, cnt는 단어 내부의 논리적 위치를 추적하는 이중 구조를 가집니다.


처음 시도했던 코드와 발생한 문제점

# 처음 시도한 코드 (틀린 코드)
def solution(s: str) -> str:
    words = s.split() # 하나 이상의 공백을 하나로 뭉쳐버림
    answer = []
    for word in words:
        weird_word = [' '] * len(word)
        for i in range(len(word)):
            weird_word[i] = word[i].lower() if i % 2 != 0 else word[i].upper()
        answer.append(''.join(weird_word))
    return ' '.join(answer) # 원본의 다중 공백이 모두 단일 공백으로 치환됨

위 코드는 "try   hello" (공백 3개)를 입력받았을 때 "TrY HeLlO" (공백 1개)를 반환하게 됩니다. 문제의 핵심은 원본 데이터의 포맷(공백 구조)을 파괴하지 않는 것에 있습니다.


3.  프로그래머스 코딩 테스트 문제 풀이 전략 교재에서 배울만한 점

제한 사항을 통한 알고리즘 선택의 직관
교재에서는 "공백이 문제라면 단순하게 생각하자"고 제안합니다. split()을 써서 단어를 나누고 다시 합치는 복잡한 과정 대신, 순회 중에 공백을 만나면 인덱스를 0으로 리셋하는 방식이 훨씬 직관적이고 실수를 줄일 수 있습니다.

문자열 수정 시 리스트 변환의 생활화
파이썬에서 문자열의 특정 인덱스 값을 직접 변경하는 것은 불가능합니다. s = list(s)를 통해 리스트로 변환한 뒤 값을 수정하고, 마지막에 ''.join(s)를 사용하는 패턴은 문자열 조작 문제의 전형적인 최적화 기법입니다.

조건부 표현식(Ternary Operators)의 활용
s[i].upper() if cnt % 2 == 0 else s[i].lower()와 같은 표현식은 코드를 간결하게 만들 뿐만 아니라, 짝수/홀수 판별 로직을 한눈에 파악하게 도와줍니다.