Algorithm/Java
[프로그래머스/JAVA] 시저암호
dbfl9911
2024. 11. 17. 18:22
https://school.programmers.co.kr/learn/courses/30/lessons/12926#
프로그래머스
SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프
programmers.co.kr
📌 문제 요약
주어진 문자열 s의 각 알파벳을 n만큼 밀어서 암호화하는 문제로, 대문자와 소문자는 각각 순환되며, 공백은 그대로 유지해야 합니다.
[ 오답 노트 ]
❌ 기존 오답 코드
class Solution {
public String solution(String s, int n) {
String answer = "";
// AB -> BC -> CD -> DE -> EF -> FG
// 1 1 1
// a B z -> b C a -> c D b -> d E c -> e F d
// 1 1 1 1
// 문자에 공백이 있을 때, 없을 때 구분?
String[] str = s.split(" "); // ["AB"] ["a", "B", "z"]
char ch;
for(int i = 0; i < str.length; i++) {
if(str[i].length() > 1) {
for(int j = 0; j < str[i].length(); j++) {
// 'A'+ 1 = "B"?
ch = (char)(Integer.parseInt(str[i].charAt(j)) + 1);
answer += String.valueOf(ch);
}
}else{
answer += str[i] + 1;
}
}
return answer;
}
}
📌 기존 코드의 문제점
1. split(" ") 사용으로 인한 공백 처리 문제
- 공백으로 문자열을 나누면 공백이 사라져 원래 문자열의 공백 정보를 잃습니다.
- 예: "a B z" → ["a", "B", "z"]
2. Integer.parseInt(str[i].charAt(j)) 사용 오류
- char 타입을 int로 변환하려면 ASCII 값을 직접 활용하거나 Character 관련 메서드를 사용해야 합니다.
- Integer.parseInt는 문자열을 숫자로 변환할 때 사용하는 메서드로 char 변환에는 부적합합니다.
3. 알파벳 범위 초과 처리 누락
- z에서 1을 더하면 a로 순환해야 하지만, 해당 처리가 없습니다.
- 대문자(A
Z)와 소문자(az)도 각각 독립적으로 순환해야 합니다.
4. else 블록의 처리 오류
- answer += str[i] + 1은 문자열과 숫자를 더해 문자열이 아닌 값이 나옵니다.
- 예: "a" + 1은 "a1"이 아니라 ASCII 값 연산이 됩니다.
[ 정답 코드 & 올바른 풀이 ]
📌 올바른 풀이
1. 공백 처리 유지
공백을 제거하지 않고 원본 문자열의 모든 문자를 순서대로 처리합니다.
2. char와 ASCII 값 활용
- char를 그대로 사용하며, 알파벳 순환을 위해 ch - 'a' 또는 ch - 'A'를 계산합니다.
3. 알파벳 순환 처리
- (ch - 'a' + n) % 26 + 'a'로 소문자를 순환 처리합니다.
- 대문자도 동일한 방식으로 처리하되, 기준값을 'A'로 설정합니다.
4. 효율적인 반복
split을 사용하지 않고, 문자열을 한 문자씩 처리하여 불필요한 배열 분할 및 추가 반복을 제거했습니다.
📌 정답 코드
class Solution {
public String solution(String s, int n) {
String answer = "";
// AB -> BC -> CD -> DE -> EF -> FG
// 1 1 1
// a B z -> b C a -> c D b -> d E c -> e F d
// 1 1 1 1
for(int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
if(ch >= 'a' && ch <= 'z') {
// 원래 알파벳 - 'a' + n = 이동된 알파벳의 위치
// 이동된 알파벳 위치 + 'a' = 이동된 알파벳
// % 26 을 하는 이유는 z + 1 했을 때 a로 순환되게 하기 위해
ch = (char)((ch - 'a' + n) % 26 + 'a');
}else if(ch >= 'A' && ch <= 'Z') {
ch = (char)((ch - 'A' + n) % 26 + 'A');
}
answer += ch;
}
return answer;
}
}