
이 문제는 프로그래머스 LV1 단계에 해당하는 시저 암호 문제다.
복잡한 알고리즘을 요구하는 문제는 아니지만, 문자의 코드값(ASCII/Unicode)과 문자 연산을 이해하는 데 도움이 되는 문제라고 생각해 정리해 보았다.
Java의 char는 Unicode를 사용하지만, 영문 알파벳(A~Z, a~z)의 코드값은 ASCII와 동일하다. 따라서 시저 암호와 같은 문제에서는 ASCII 코드의 개념으로 이해해도 무방하다. 문자도 내부적으로는 숫자로 저장되기 때문에 숫자처럼 덧셈과 뺄셈 연산을 할 수 있다.
따라서 이 문제는 영문 알파벳이 연속된 코드값을 가진다는 점과, 문자를 숫자처럼 더하고 뺄 수 있다는 점을 이용해 해결할 수 있다.
| 문자 | 코드 | 'A'를 뺀 결과 |
| A | 65 | 0 |
| B | 66 | 1 |
| C | 67 | 2 |
| ... | ... | ... |
| X | 88 | 23 |
| Y | 89 | 24 |
| Z | 90 | 25 |
위 표를 보면 c - 'A'의 결과가 알파벳의 순서(0~25)를 의미한다는 것을 쉽게 이해할 수 있다.
이 문제 특성상 공백은 공백으로 두고 대문자 혹은 소문자만 n만큼 이동한 문자로 이루어진 새로운 문자열을 만들어야 한다.
따라서 for 문 안 if 문을 통해 공백, 대문자, 소문자일 때를 구분해야 한다.
문제는 그냥 더하기만 하면 안 된다는 것이다.
문제를 읽어보면 "z"를 1만큼 밀면 "a"가 된다는 조건 때문이다.
즉, 알파벳 마지막 문자를 넘어가면 그 다음 ASCII 코드로 넘어가는 것이 아닌 대문자, 소문자 각각 그 루프 안에서 순환한다는 것을 유의해야 한다.
총 알파벳은 a~z, A~Z 각각 26개로 이루어져있다.
따라서 0번 알파벳부터 25번 알파벳이라고 생각하면 문제 접근하는 것이 좀 더 쉬워진다.
예를 들어 24번 알파벳을 3만큼 이동시키면 24 -> 25 -> 1 -> 2 가 되므로 b혹은 B가 된다.
이해를 돕기 위한 버전이다.
아래 코드는 문자를 n만큼 이동시킨 결과가 대문자의 마지막 문자('Z') 또는 소문자의 마지막 문자('z')를 넘어가는 경우 26을 빼 다시 처음으로 돌아오도록 구현한 것이다.
char c = s.charAt(i);
if (c == ' ') {
sb.append(' ');
} else if ('A' <= c && c <= 'Z') {
if (c + n > 'Z') {
sb.append((char)(c + n - 26));
} else {
sb.append((char)(c + n));
}
} else {
if (c + n > 'z') {
sb.append((char)(c + n - 26));
} else {
sb.append((char)(c + n));
}
}
위의 코드를 굳이 26보다 클 때와 작을 때로 구분하지 않고 하나로 나타낼 수 있는 것은 '%' 연산자를 이용하는 것이다.
(char)('A' + (c - 'A' + n) % 26)
(char)('a' + (c - 'a' + n) % 26)
c - 'A'를 통해 문자를 0~25 범위의 숫자로 변환한 뒤 n만큼 이동시키고, % 26으로 다시 0~25 범위 안에서 순환하도록 만든 후 마지막으로 'A'를 더해 다시 문자로 변환하는 방식이다.
이렇게 하면 한 줄로 표현 가능하다.
이건 내가 정답으로 제출한 코드다.
class Solution {
public String solution(String s, int n) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c == ' ') {
sb.append(' ');
} else if ('A' <= c && c <= 'Z') {
sb.append((char)('A' + (c - 'A' + n) % 26));
} else {
sb.append((char)('a' + (c - 'a' + n) % 26));
}
}
return sb.toString();
}
}
추가로 (char) 형변환 부분에 대해 첨언해보자면
char c = 'A';
sb.append(c + 1);
에 대한 결과는 66이다.
이유는 자바의 자동형변환 때문이다.
byte
↓
short
↓
char
↓
int
↓
long
↓
float
↓
double
Java에서는 연산 과정에서 위와 같은 순서로 자동 형변환이 일어난다.
char + int의 결과는 int이기 때문에 명시적으로 char 형태로 형변환을 해야 우리가 원하는 결과를 얻을 수 있다.
즉, 우리가 원하는 것은 66이아닌 B이므로 char 형태로 형변환을 해야한다.
이번 문제는 단순한 문자열 문제가 아니라 문자도 내부적으로는 숫자로 저장된다는 점과, Java의 자동 형변환 및 문자 연산을 이해하는 데 좋은 문제였다.
'PS' 카테고리의 다른 글
| [프로그래머스] 숫자 문자열과 영단어 (0) | 2026.07.07 |
|---|---|
| [프로그래머스] 푸드 파이트 대회 (0) | 2026.07.05 |
| [프로그래머스] 이상한 문자 만들기 (0) | 2026.06.25 |
| [프로그래머스] 최대공약수와 최소공배수 (0) | 2026.06.23 |
| [프로그래머스] 두 개 뽑아서 더하기 (1) | 2026.06.12 |