본문 바로가기
AI/Coding_Test

Day 10) 프로그래머스 파이썬 문자열 5문제 풀이

by 거대웅 TitanBear 2026. 7. 17.

Programmers Coding Test · Day 10 · Python

문자열 문제 5개 풀이

앞부분 자르기부터 접두사, 부분 뒤집기, 세로 읽기, QR 코드까지 문자열 인덱스를 다루는 방법을 한 번에 복습했다.

Day 10은 다섯 문제 모두 문자열을 다룬다. 겉보기에는 서로 다른 문제지만, 실제로는 시작 위치, 끝 위치, 간격을 어떻게 정하느냐가 핵심이었다. 먼저 반복문으로 조건을 직접 확인하고, 그다음 파이썬의 슬라이싱으로 코드를 줄여 보니 각 문법이 어떤 역할을 하는지 더 분명하게 보였다.

오늘의 핵심 파이썬 슬라이싱 문자열[시작:끝:간격]에서 위치의 문자는 포함되지 않는다. 문제에서 마지막 인덱스까지 포함하라고 하면 보통 끝 + 1이 필요하다.

Day 10 문제와 공식 링크

1
인덱스 기준부터 확인하기파이썬 문자열 인덱스는 0부터 시작하지만, 문제의 열 번호 c는 1부터 시작한다.
2
포함 범위를 확인하기s부터 e까지 모두 포함하려면 슬라이싱의 끝을 e + 1로 잡아야 한다.
3
문자와 인덱스를 구분하기QR 코드 문제는 문자의 값이 아니라 문자가 놓인 인덱스q로 나눈 나머지를 검사한다.

1. 문자열의 앞의 n글자

my_string의 맨 앞에서부터 n글자를 반환하는 문제다. 처음에는 반복문으로 앞의 문자를 하나씩 이어 붙일 수 있다.

기본 풀이: 반복문으로 직접 누적하기

def solution(my_string, n):
    answer = ''

    for i in range(n):
        answer += my_string[i]

    return answer

range(n)0부터 n - 1까지 만든다. 따라서 앞의 n글자를 정확히 한 번씩 가져올 수 있다.

더 간단한 풀이: 슬라이싱

def solution(my_string, n):
    return my_string[:n]
[:n]은 왜 n글자일까? 시작 위치를 생략하면 처음부터 자르고, 끝 위치 n은 포함하지 않는다. 결국 인덱스 0부터 n - 1까지, 총 n글자가 남는다.

2. 접두사인지 확인하기

접두사는 문자열의 맨 앞에서 시작하는 문자열이다. 예를 들어 banana 안에 nan이 들어 있기는 하지만 맨 앞에서 시작하지 않으므로 접두사가 아니다.

기본 풀이: 앞부분을 잘라 비교하기

def solution(my_string, is_prefix):
    if my_string[:len(is_prefix)] == is_prefix:
        return 1
    return 0

is_prefix의 길이만큼 my_string 앞부분을 잘라 두 문자열이 같은지 확인했다. 접두사가 원본 문자열보다 길어도 슬라이싱은 오류 없이 가능한 범위까지만 반환하므로 결과는 자연스럽게 0이 된다.

더 간단한 풀이: startswith()

def solution(my_string, is_prefix):
    return int(my_string.startswith(is_prefix))

startswith()는 특정 문자열로 시작하면 True, 아니면 False를 반환한다. 여기에 int()를 적용하면 각각 1과 0으로 바뀐다.

주의: in을 쓰면 다른 문제가 된다 is_prefix in my_string은 문자열이 중간이나 끝에 있어도 참이 된다. 이 문제는 포함 여부가 아니라 맨 앞에서 시작하는지를 확인해야 한다.

3. 문자열 뒤집기

my_string 전체를 뒤집는 문제가 아니라, 인덱스 s부터 e까지의 구간만 뒤집어야 한다. 문자열을 앞, 뒤집을 구간, 뒤의 세 부분으로 나누면 이해하기 쉽다.

내가 작성한 코드

def solution(my_string, s, e):
    answer = my_string[:s] + my_string[e:s - 1:-1] + my_string[e + 1:]
    return answer

문자열을 앞부분, 뒤집을 구간, 뒷부분으로 나눠 다시 조립하려는 방향은 정확했다. 특히 가운데 구간에서 간격을 -1로 두어 역순으로 읽으려 한 점이 좋았다.

s = 0일 때 생기는 숨은 문제 s - 1-1이 된다. 이때 my_string[e:-1:-1]-1은 단순히 처음보다 앞이라는 뜻이 아니라 문자열의 마지막 인덱스로 해석된다. 역방향 슬라이싱의 끝 위치는 포함되지 않기 때문에 원하는 구간 대신 빈 문자열이 나올 수 있다.

안전하게 고친 기본 풀이

def solution(my_string, s, e):
    front = my_string[:s]
    middle = my_string[s:e + 1]
    back = my_string[e + 1:]

    return front + middle[::-1] + back
1
앞부분my_string[:s]s 바로 전까지 보존한다.
2
가운데 구간my_string[s:e + 1]로 먼저 안전하게 자른 뒤 [::-1]로 뒤집는다.
3
뒷부분my_string[e + 1:]로 뒤집을 범위 다음의 문자를 이어 붙인다.

한 줄로 정리한 풀이

def solution(my_string, s, e):
    return my_string[:s] + my_string[s:e + 1][::-1] + my_string[e + 1:]
가장 자주 생기는 실수 가운데를 my_string[s:e]로 자르면 인덱스 e의 문자가 빠진다. 문제의 범위는 se를 모두 포함하므로 e + 1이 필요하다.

4. 세로 읽기

문자열을 한 줄에 m글자씩 나누었을 때, 왼쪽에서 c번째 열의 문자를 위에서 아래로 읽는 문제다. 같은 열의 문자는 인덱스가 m씩 증가한다.

내가 작성한 코드

def solution(my_string, m, c):
    answer = ''
    new = list(my_string.split(' '))

    for i in new[c - 1::m]:
        answer += my_string[i]

    return answer

[c - 1::m]으로 일정한 간격의 값을 고르려 한 방향은 문제의 핵심과 맞았다. 다만 슬라이싱을 적용한 대상과 반복문 변수 i의 자료형 때문에 코드가 정상적으로 실행되지 않는다.

1
split(' ')은 필요하지 않다입력 문자열에는 공백이 없다. 따라서 분리하면 글자 목록이 아니라 원본 문자열 하나를 담은 리스트가 된다.
2
i는 인덱스가 아니다for i in new[...]에서 i는 숫자가 아니라 문자열 값이다. my_string[i]처럼 문자열을 인덱스로 사용하면 TypeError가 발생한다.

초보자가 이해하기 쉬운 기본 풀이

def solution(my_string, m, c):
    answer = ''

    for i in range(c - 1, len(my_string), m):
        answer += my_string[i]

    return answer

range(c - 1, len(my_string), m)c - 1에서 시작해 m칸씩 증가하는 인덱스를 만든다. 이제 i가 실제 숫자 인덱스이므로 my_string[i]로 문자를 안전하게 꺼낼 수 있다.

더 간단한 풀이: 간격이 있는 슬라이싱

def solution(my_string, m, c):
    return my_string[c - 1::m]

[c - 1::m]은 인덱스 c - 1에서 시작해 끝까지 m칸 간격으로 문자를 선택한다. 반복문의 범위와 슬라이싱의 세 요소가 정확히 대응한다.

예제로 인덱스 확인하기 m = 4, c = 2라면 선택되는 인덱스는 1, 5, 9, 13, 17이다. 공식 예제 문자열에서 이 문자를 이어 붙이면 happy가 된다.

5. qr code

code의 각 인덱스를 q로 나누었을 때 나머지가 r인 위치의 문자만 순서대로 이어 붙이는 문제다.

내가 처음 작성한 코드

def solution(q, r, code):
    answer = ''

    for i in code:
        if r == i % q:
            answer += i

    return answer

나머지 연산으로 조건을 확인하려는 생각은 맞았다. 하지만 for i in code에서 i에는 인덱스가 아니라 'a', 'b' 같은 문자가 들어간다. 문자열에 나머지 연산을 적용할 수 없으므로 TypeError가 발생한다.

기본 풀이: 인덱스를 직접 반복하기

def solution(q, r, code):
    answer = ''

    for i in range(len(code)):
        if i % q == r:
            answer += code[i]

    return answer

range(len(code))를 사용하면 i가 0부터 시작하는 인덱스가 된다. 나머지 조건은 i로 확인하고, 선택한 문자는 code[i]로 가져오면 된다.

내가 수정한 최종 풀이: r에서 시작해 q칸씩 이동하기

def solution(q, r, code):
    return code[r::q]

인덱스를 q로 나눈 나머지가 r인 위치는 r, r + q, r + 2q, ...로 이어진다. 따라서 인덱스 r에서 시작해 q칸씩 건너뛰는 슬라이싱으로 같은 결과를 얻을 수 있다.

주의: r이 0일 수도 있다 제한사항은 0 ≤ r < q다. 나머지가 0인 인덱스도 선택 대상이므로 시작 위치를 임의로 1로 고정하면 안 된다.

공식 예제로 한 번에 검산하기

각 문제의 대표 입력과 결과
문제 대표 입력 결과
앞의 n글자 "ProgrammerS123", 11 "ProgrammerS"
접두사 "banana", "ban" 1
문자열 뒤집기 "Progra21Sremm3", 6, 12 "ProgrammerS123"
세로 읽기 "ihrhbakrfpndopljhygc", 4, 2 "happy"
qr code 3, 1, "qjnwezgrpirldywt" "jerry"

이번 문제에서 기억할 실수 체크리스트

  • 슬라이싱의 끝 인덱스는 결과에 포함되지 않는다.
  • 문제의 위치가 1부터 시작하는지, 인덱스가 0부터 시작하는지 확인한다.
  • 접두사 문제에서 단순 포함 연산자 in을 사용하지 않는다.
  • 부분 문자열 뒤집기에서는 앞, 가운데, 뒤 구간을 빠뜨리지 않는다.
  • QR 코드 문제는 문자의 값이 아니라 인덱스의 나머지를 검사한다.
  • 짧은 풀이를 외우기 전에 반복문이 어떤 위치를 선택하는지 먼저 설명해 본다.

같이 보면 좋은 개념

1
문자열 슬라이싱[시작:끝:간격]의 세 자리에 어떤 값이 들어가는지 예제로 익혀 두면 네 문제를 거의 같은 방식으로 풀 수 있다.
2
문자열 메서드startswith()endswith()의 차이를 함께 비교하면 접두사와 접미사를 헷갈리지 않는다.
3
enumerate()문자열이나 리스트를 반복하면서 인덱스와 값을 모두 사용해야 할 때 유용하다.