[Java] 시저 암호 Lv1

Date:     Last Updated:

시저 암호

문제 프로그래머스 FAQ 내용을 보니 카카오나 기업의 문제들은 저작권이 있으니 풀이를
github나 개인블로그에 올리지 말라고 되어 있어서 링크로 대체합니다.

출처: Programmers
시저 암호

문제의 이해

문제를 보자마자 간단한 아스키코드 문제라고 생각했다. 실제로 간단했는데 간단하다고 방심을 한게 문제였었는지 오류가 나는 부분이 있어서 꽤 애먹었다. 대문자는 65~90, 소문자는 97부터 122부터니까 그것만 잘 컨트롤 하면 된다고 생각했다.

내가 생각한 풀이 방법

  1. 주어진 문자열을 char형으로 배열로 변환 후 반복한다.
  2. 아스키 코드에서 공백을 만나면 패스
  3. 공백이 아닌 문자를 만나면 주어진 n만큼 민다.
  4. 이때 밀어버린 값이 122 or 90을 넘어서면(알파벳의 범위를 벗어난) 123 or 91로 나누고 97 or 65를 더해준다.
  5. char배열을 다시 문자열로 변환

풀이

첫 번째 풀이

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import java.util.Arrays;
import java.util.regex.*;

class Solution {
    public String solution(String s, int n) {
        String answer = "";
        char[] strArr = s.toCharArray();    //문자열의 각 알파벳에 직접 접근하기 위해서 문자열을 char 배열로 변환
        
        //알파벳의 아스키 코드는 대문자부터 65~122까지
        for(int i = 0; i < strArr.length; i++){
            
            if(((int)(strArr[i])) == 32)    //이때 32는 공백문자다. 공백문자를 만나면 패스~
            {
                continue;
            }
            //strArr[i] = (char)(strArr[i] + n);  //공백문자가 아니라면 해당 문자에 주어진 n을 더한다.
            
            
            
            //이 부분은 z에서 밀면 다시 a로 가야해서 아스키 코드값 z+1인 123으로 나누고 +97을 해서 a로 오게 만든다.
            //여기 부분이 문제가 있었던 듯 이 코드는 소문자는 잘 밀어주는데 대문자는 제대로 밀지 못함.
            if((int)(strArr[i]) <= 122 && (int)(strArr[i]) >= 97){     
                strArr[i] = (char)(strArr[i] + n);
                if((int)(strArr[i]) > 122){
                    strArr[i] = (char)(strArr[i] % 123 + 97);
                }
            }
            else if((int)(strArr[i]) <= 90 && (int)(strArr[i]) >= 65){   
                strArr[i] = (char)(strArr[i] + n);
                if((int)(strArr[i]) > 90){
                    strArr[i] = (char)(strArr[i] % 91 + 65);
                }
            }
        }
        answer = String.copyValueOf(strArr);    //char배열을 다시 문자열로 변환
        
        return answer;
    }
}

두 번째 풀이

오늘 도저히 머리가 안돌아가서 포기하려고 했으나 아무리 그래도 완전 똑같은 중복코드를 남겨둘 수 는 없어서 어떻게 해서든 중복 코드만 제거 했다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import java.util.Arrays;
import java.util.regex.*;

class Solution {
    public String solution(String s, int n) {
        String answer = "";
        char[] strArr = s.toCharArray();    //문자열의 각 알파벳에 직접 접근하기 위해서 문자열을 char 배열로 변환
        int maxValue = 0;
        int minValue = 0;
        
        //알파벳의 아스키 코드는 대문자부터 65~122까지
        for(int i = 0; i < strArr.length; i++){
            
            if(((int)(strArr[i])) == 32)    //이때 32는 공백문자다. 공백문자를 만나면 패스~
            {
                continue;
            }
            //strArr[i] = (char)(strArr[i] + n);  //공백문자가 아니라면 해당 문자에 주어진 n을 더한다.
            
            //이 부분은 z에서 밀면 다시 a로 가야해서 아스키 코드값 z+1인 123으로 나누고 +97을 해서 a로 오게 만든다.
            //여기 부분이 문제가 있었던 듯 이 코드는 소문자는 잘 밀어주는데 대문자는 제대로 밀지 못함.
            
            if((int)(strArr[i]) > 90){ //90보다 아스키 코드 값이 크면 소문자
                maxValue = 122;
                minValue = 97;
            }
            else
            {
                maxValue = 90;
                minValue = 65;
            }
            
            if((int)(strArr[i]) <= maxValue && (int)(strArr[i]) >= minValue){
                strArr[i] = (char)(strArr[i] + n);
                if((int)(strArr[i]) > maxValue){
                    strArr[i] = (char)(strArr[i] % (maxValue + 1) + minValue);
                }
            }
        }
        answer = String.copyValueOf(strArr);    //char배열을 다시 문자열로 변환
        
        return answer;
    }
}


Leave a comment