
문제
https://school.programmers.co.kr/learn/courses/30/lessons/12926
프로그래머스
SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프
programmers.co.kr
문제 설명
- 시저 암호 : 어떤 문장의 각 알파벳을 일정한 거리만큼 밀어서 다른 알파벳으로 바꾸는 암호화 방식
- 예시1) "AB"는 1만큼 밀면 "BC"가 되고, 3만큼 밀면 "DE"
예시2) "z"는 1만큼 밀면 "a" - 문자열 s와 거리 n을 입력받아 s를 n만큼 민 암호문을 만드는 함수 반환
- 제한 조건)
공백은 아무리 밀어도 공백
s는 알파벳 소문자, 대문자, 공백으로만 이루어짐
s의 길이는 8000이하
n은 1 이상, 25이하인 자연수
풀이 흐름
1. 문자 하나씩 처리
- 입력 문자열 s를 한 글자씩 순회하면서,
- 알파벳이면 밀어주고, 공백이면 그대로 두기
2. 문자 밀기 (알파벳의 경우)
- 알파벳은 유니코드(아스키) 코드로 변환해서 처리 → ord()
- 밀고 나서 다시 문자로 변환할 때는 chr() 사용
- 밀었을 때 Z나 z를 넘어가면 다시 A 또는 a로 돌아가야 함 → 나머지 연산(%)를 활용
3. 대문자/소문자 구분
- if c.isupper(): 또는 if c.islower():로 구분
4. 공백은 그대로 두기
- ' '이면 answer에 그대로 추가
정답 코드
def solution(s, n):
answer = ''
for i in s:
if i == ' ':
answer += ' '
else:
base = ord('A') if i.isupper() else ord('a')
answer += chr((ord(i) - base + n) % 26 + base)
return answer
코드 설명
else:
base = ord('A') if i.isupper() else ord('a')
- 현재 문자가 알파벳일 때
- 대문자면 `'A'`, 소문자면 `'a'`의 ASCII 코드(`ord`)를 기준점으로 사용
- 왜 필요하냐면?
- 알파벳을 0~25 범위로 바꾼 다음 밀고 다시 문자로 바꿔야 하기 때문
예: `'a'` → 0, `'z'` → 25
- 알파벳을 0~25 범위로 바꾼 다음 밀고 다시 문자로 바꿔야 하기 때문
answer += chr((ord(i) - base + n) % 26 + base)
- ord(i) - base
- base는 'a' 또는 'A'
- 이걸 빼면, 알파벳 기준으로 0~25로 정규화 가능

- + n
- 몇 칸 밀건지 정해주는 부분
- (...) % 26
- 알파벳 26글자이므로, z를 넘어가면 다시 a로 돌아오게 함
- + base
- 다시 원래 문자 영역으로 복원
- chr(...)
- 문자로 변환
- 풀이 예시) 'z', n = 1 → 'a'
→ ord('z') = 122, base = 97
→ (122 - 97 + 1) % 26 = 0
→ chr(0 + 97) = 'a'
참고) 성능 측면 (대량 입력 시)
- result += ...를 반복하면, 이건 문자열이 불변이기 때문에
- 매번 새로운 문자열을 생성
- 반복 횟수가 많으면 느릴 수 있음 (예: 1만 글자 이상)
- 리스트에 .append()하고 마지막에 ''.join(...) 사용
def solution(s, n):
result = []
for c in s:
if c == ' ':
result.append(' ')
else:
base = ord('A') if c.isupper() else ord('a')
result.append(chr((ord(c) - base + n) % 26 + base))
return ''.join(result)
- 입력 길이가 작다면 굳이 사용할 필요는 없음
첫 번째 시도 (실패)
def solution(s, n):
answer = ''
for i in s:
if i == ' ':
result = answer.append(' ')
else:
if i.upper():
first = ord('A')
elif i.lower():
first = ord('a')
result = answer.append(chr(first + (ord(i)-first+n)%26))
return result
문제점
- result = answer.append(...)
- str.append()는 없음 (문자열은 변경 불가이기 때문에 append() 사용 못함)
- 그리고, append()는 리스트에 쓰는 메서드
- 해결 방법
- 방법 1: answer를 문자열로 유지하고 +=로 붙이기
- 방법 2: answer를 리스트로 만들고 마지막에 ''.join(answer)로 결합
- if i.upper():과 elif i.lower():
- i.upper()는 항상 문자열을 반환하므로 조건문에 쓰면 무조건 True
- 해결 방법
- i.isupper()와 i.islower()를 사용
두 번째 시도 (성공. 효율 개선 필요)
def solution(s, n):
answer = ''
for i in s:
if i == ' ':
answer += ' '
else:
if i.isupper():
first = ord('A')
elif i.islower():
first = ord('a')
answer += chr(first + (ord(i)-first+n)%26)
return answer'코딩 테스트 연습 > [프로그래머스] Python' 카테고리의 다른 글
| [LV.3] 연습문제 > 문자열 내 마음대로 정렬하기 ⭐️ (1) | 2025.07.08 |
|---|---|
| [LV.3] 숫자 문자열과 영단어 ⭐ (0) | 2025.07.07 |
| [LV.3] 완전탐색 > 최소직사각형 (0) | 2025.07.03 |
| [LV.3] 연습문제 > 크기가 작은 부분문자열 (1) | 2025.07.02 |
| [LV.3] 연습문제 > 삼총사 ⭐️ (1) | 2025.07.01 |