Programmers Coding Test · Day 10 · Python
문자열 문제 5개 풀이
앞부분 자르기부터 접두사, 부분 뒤집기, 세로 읽기, QR 코드까지 문자열 인덱스를 다루는 방법을 한 번에 복습했다.
Day 10은 다섯 문제 모두 문자열을 다룬다. 겉보기에는 서로 다른 문제지만, 실제로는 시작 위치, 끝 위치, 간격을 어떻게 정하느냐가 핵심이었다. 먼저 반복문으로 조건을 직접 확인하고, 그다음 파이썬의 슬라이싱으로 코드를 줄여 보니 각 문법이 어떤 역할을 하는지 더 분명하게 보였다.
문자열[시작:끝:간격]에서 끝 위치의 문자는 포함되지 않는다. 문제에서 마지막 인덱스까지 포함하라고 하면 보통 끝 + 1이 필요하다.
Day 10 문제와 공식 링크
| 순서 | 문제 | 핵심 문법 |
|---|---|---|
| 1 | 문자열의 앞의 n글자 | my_string[:n] |
| 2 | 접두사인지 확인하기 | startswith() |
| 3 | 문자열 뒤집기 | [::-1], 구간 분리 |
| 4 | 세로 읽기 | [c - 1::m] |
| 5 | qr code | index % q == r |
c는 1부터 시작한다.s부터 e까지 모두 포함하려면 슬라이싱의 끝을 e + 1로 잡아야 한다.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
my_string[:s]로 s 바로 전까지 보존한다.my_string[s:e + 1]로 먼저 안전하게 자른 뒤 [::-1]로 뒤집는다.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의 문자가 빠진다. 문제의 범위는 s와 e를 모두 포함하므로 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의 자료형 때문에 코드가 정상적으로 실행되지 않는다.
split(' ')은 필요하지 않다입력 문자열에는 공백이 없다. 따라서 분리하면 글자 목록이 아니라 원본 문자열 하나를 담은 리스트가 된다.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칸씩 건너뛰는 슬라이싱으로 같은 결과를 얻을 수 있다.
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 코드 문제는 문자의 값이 아니라 인덱스의 나머지를 검사한다.
- 짧은 풀이를 외우기 전에 반복문이 어떤 위치를 선택하는지 먼저 설명해 본다.
같이 보면 좋은 개념
[시작:끝:간격]의 세 자리에 어떤 값이 들어가는지 예제로 익혀 두면 네 문제를 거의 같은 방식으로 풀 수 있다.startswith()와 endswith()의 차이를 함께 비교하면 접두사와 접미사를 헷갈리지 않는다.'AI > Coding_Test' 카테고리의 다른 글
| Day 10)프로그래머스 파이썬 풀이: 과일 장수, 소수 만들기, 오픈채팅방, 개미 군단, 컨트롤 제트 (0) | 2026.07.15 |
|---|---|
| Day 9) 프로그래머스 문자열 문제: 리스트 컴프리헨션, zip, 슬라이싱, 접미사 풀이 정리 (0) | 2026.07.14 |
| Day 8) 프로그래머스 조건문·문자열: 논리 연산, 주사위 게임 3, 문자열 만들기, 9로 나눈 나머지 (0) | 2026.07.13 |
| Day 7) 프로그래머스 반복문: 구간 쿼리, 배열 만들기, 콜라츠, 스택 풀이 정리 (0) | 2026.07.12 |
| Day 6)Programmers Coding Test (0) | 2026.07.11 |