코딩 테스트 연습/[프로그래머스] Python

[LV.3] 연습문제 > 이상한 문자 만들기 ⭐

duswjd_data 2025. 6. 30. 09:55

문제

https://school.programmers.co.kr/learn/courses/30/lessons/12930

 

프로그래머스

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

programmers.co.kr


문제 설명

  • 문자열 s는 한 개 이상의 단어로 구성
  • 각 단어는 하나 이상의 공백문자로 구분
    각 단어의 짝수번째 알파벳은 대문자로, 홀수번째 알파벳은 소문자로 바꾼 문자열을 반환
  • 제한 사항)
    문자열 전체의 짝/홀수 인덱스가 아니라, 단어(공백을 기준)별로 짝/홀수 인덱스를 판단
    첫 번째 글자는 0번째 인덱스로 보아 짝수번째 알파벳으로 처리

정답 코드

def solution(s):
    words=s.split(" ")
    result = []
    
    for word in words:
        new_word = ""
        for i in range(len(word)):
            if i%2==0:
                new_word += word[i].upper()
            else:
                new_word += word[i].lower()
        result.append(new_word)
    return ' '.join(result)

코드 설명

def solution(s):
    words = s.split(" ")  # 문자열을 공백 기준으로 나눠서 단어 리스트 생성 (공백 여러 개도 반영됨)
    result = []           # 변환된 단어들을 저장할 리스트

    for word in words:    # 각 단어에 대해 반복
        new_word = ""     # 변환된 단어를 저장할 임시 문자열
        for i in range(len(word)):  # 단어의 각 문자에 인덱스를 붙여 반복
            if i % 2 == 0:                   # 짝수 인덱스라면
                new_word += word[i].upper()  # 대문자로 변환하여 추가
            else:                            # 홀수 인덱스라면
                new_word += word[i].lower()  # 소문자로 변환하여 추가
        result.append(new_word)     # 변환된 단어를 결과 리스트에 추가

    return ' '.join(result)         # 변환된 단어들을 다시 공백으로 연결하여 반환

개선 방식

1. enumerate 활용 → 가독성 향상

  • 반복문에서 인덱스와 값을 동시에 꺼낼 수 있게 해주는 함수
  • 기본문법
for i, value in enumerate(리스트):

 

  • i → 인덱스 (0부터 시작)
  • value → 리스트나 문자열 등에서 꺼낸 값

  • for i in range(len(word)) 보다
    for i, c in enumerate(word)

 

for i, c in enumerate(word):
    if i % 2 == 0:
        new_word += c.upper()
    else:
        new_word += c.lower()

 

2. 문자열 누적 대신 리스트 + join 사용 → 성능 향상

  • new_word += ...는 문자열을 계속 새로 만들기 때문에 비효율적
    리스트에 추가한 뒤 ''.join(...)이 메모리와 속도 측면에서 더 좋음
temp = []
for i, c in enumerate(word):
    temp.append(c.upper() if i % 2 == 0 else c.lower())
new_word = ''.join(temp)

개선 코드

def solution(s):
    words = s.split(' ')
    result = []

    for word in words:
        temp = []
        for i, c in enumerate(word):
            temp.append(c.upper() if i % 2 == 0 else c.lower())
        new_word = ''.join(temp)
        result.append(new_word)

    return ' '.join(result)

 

  • enumerate(word) → 각 문자와 인덱스를 동시에 순회
  • temp.append(...) → 변환된 문자들을 리스트에 저장
  • ''.join(temp) → 문자 리스트를 하나의 문자열로 합침
  • result.append(new_word) → 변환된 단어를 최종 리스트에 추가
  • ' '.join(result) → 단어들 사이에 공백을 두고 연결

 


첫 번째 시도 (실패)

def solution(s):
    words=s.split(" ")
    for word in words:
        new_word = ""
        for i in range(len(word)):
            if i%2==0:
                new_word = new_word + word[i].upper()
            else:
                new_word = new_word + word[i]
    return ''.join(new_word)

틀린 이유

  • new_word가 단어마다 덮어쓰기 되고 있음
    • 전체 결과를 담는 리스트가 없음 → 마지막 단어만 리턴됨
  • else에서 소문자로 변환 빠짐
    • 문제 조건은 '짝수는 대문자, 홀수는 소문자'인데,
      지금은 그냥 word[i] 그대로 넣어서 대문자인 경우 그대로 유지됨

두 번째 시도 (실패)

def solution(s):
    words=s.split(" ")
    for word in words:
        new_word = ""
        for i in range(len(word)):
            if i%2==0:
                result = new_word + word[i].upper()
            else:
                result = new_word + word[i].lower()
    return ''.join(result)

틀린 이유

  • 누적되는게 아니라 덮어쓰기 되고 있음

세 번째 시도 (실패)

def solution(s):
    words=s.split(" ")
    for word in words:
        new_word = ""
        for i in range(len(word)):
            if i%2==0:
                new_word += word[i].upper()
            else:
                new_word += word[i].lower()
        result.append(new_word)
    return ''.join(result)

틀린 이유

  • result라는 리스트를 만들지 않고 append를 하고 있어서 오류 발생
  • return ''.join(result)
    • 단어 사이 공백 없이 반환 (문제에서는 공백 있게 반환해야 됨)