자바 초급문제로 맨땅에 해딩하기

자바 초급문제 12. 시저 암호

Jungsoomin :) 2020. 4. 5. 00:00

프로그래머스(https://programmers.co.kr/learn/courses/30/lessons/12926)

자바 초급 문제의 시저 암호 이다.

 

문제 설명

어떤 문장의 각 알파벳을 일정한 거리만큼 밀어서 다른 알파벳으로 바꾸는 암호화 방식을 시저 암호라고 합니다. 예를 들어 AB는 1만큼 밀면 BC가 되고, 3만큼 밀면 DE가 됩니다. z는 1만큼 밀면 a가 됩니다. 문자열 s와 거리 n을 입력받아 s를 n만큼 민 암호문을 만드는 함수, solution을 완성해 보세요.

제한 조건

  • 공백은 아무리 밀어도 공백입니다.

  • s는 알파벳 소문자, 대문자, 공백으로만 이루어져 있습니다.

  • s의 길이는 8000이하입니다.

  • n은 1 이상, 25이하인 자연수입니다.

 

 

식사를 하고 설겆이를 마치고 강의를 마저 듣고나서 저녁 10시 즈음에 문제를 잡았다. 푸는 시간은 1h20m가량 걸린 듯 하다. 개인적으로 기쁘고 뿌듯하기도하고 스스로가 그만큼 부끄러워지기도 하는 것 같아 스스로 겸손한 마음을 가지게 된다. 생각보다 시간을 단축시켜서 행복하다. 그럴 수 있던 이유에는 코드를 짜는 시간보다는 규칙을 이해하는데 굉장히 중점을 두고 종이에 써내려가며 틀을 잡고 시작했다는 점이 있는 것 같다. 문득 char타입을 int타입으로 돌릴 수 있고 합산시 int타입으로 자동변환된다는 교재의 내용이 떠올라서 복습과 실습을 겸하기위해 그 점을 근간으로 잡고 시작했다.

타입변환을 이용하자는 생각을 하고 그 후에 char 타입 배열에 담아 String 타입으로 바꿔 answer를 제출하자고 생각했다. 그렇게 진행을 해보니 코딩하는 시간은 생각보다도 더 짧아진 듯 하다. 굉장히 감사한 일이다. 

 

코드에 굳이 타입변환을 하지않아도 되는 경우를 보시게 될 듯 하다. int타입으로 굳이 변환한 경우이다. 자동 타입 변환 됬을텐데.. 개인적 심정이지만...제출 전에 한번 더 고려하면 좋았을 걸...한다.

 

로직에 큰 규칙을 세워줘야한다는 점에서 배울 점이 많았다.

 

// 주어지는 문자열은 s 미는 칸은 n 미는칸만큼 알파벳이 움직임
// 알파벳 문자열이 필요함.
// char형으로 뽑아서 유니코드 를 증가시키면 어떤가.
// char에서 A는 10진수로 65임 +25는 Z(90) 여기까지 돌아감.
// char에서 a는 10진수로 97임 +25는 z(122) 여기까지.
// n이 +값 , s가 주어지는 문자열 / 공백은 10진수로 32

 

아..그리고 공책에 적은 규칙은 (String 타입 s의 각 글자의 10진수의 변환 값 + 미는 칸  n) 이 마지막 알파벳인 90이나 122보다 크다면

 

( (더한 수(코드에서는 check+n) - 90or122)-1 ) +첫글자인 65or97 이 밀어낸 후의 소문자(65~90)or대문자(97~122)의 알파벳이 된다.는 점이다.

공책에 적어가며 가설을 세우며 계산한 결과 맞아떨어졌다. 나에겐 찾아온 행운인 것 같아서 고마워하고 기뻐했다.

 

시작하기전에 이클립스에 타이핑 해놓은 규칙이다. 코드를 볼때에 조금이라도 편하지않을까 싶은 마음에 올려두고 싶다.

전체주석으로 잡으면 나누어 보기 힘들어 1열 주석으로 처리한 점 이해해주시길 바란다.

 

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
package programmers_시저암호;
 
public class SubClass {
    public String solution(String s, int n) {
        String answer = "";
        char check;
        char[] arr = new char[s.length()];// s의 문자열 길이만큼의 char배열
        int save = 0;// 저장한 후 char로 저장할 것임.
 
        for (int i = 0; i < s.length(); i++) {// s의 문자열 수만큼 돔
            check = s.charAt(i);// 하나씩 검사.
            if (check == 32) {// 공백이라면
                save = 32;
                arr[i] = (char) save;// 그냥 넣는다.
            }
            if ((int) check > 64 && (int) check < 91) {// 대문자일 때에
                if ((int) check + n > 90) {// n을 더한 값이 유니코드표를 벗어나게되면
                    save = 65 + (((check + n) - 90- 1);
                    arr[i] = (char) save;
                    // 해당 순번의 10진수 char로 강제변환해서 배열에 저장.
                } else {
                    save = check + n;// 작다면 그냥더함
                    arr[i] = (char) save;// 저장
                }
            } else if ((int) check > 96 && (int) check < 123) {// 소문자라면
                if ((int) check + n > 122) {// 더한값이 유니코드 표를 벗어나면
                    save = 97 + (((check + n) - 122- 1);
                    arr[i] = (char) save;
                } else {
                    save = check + n;
                    arr[i] = (char) save;
                }
            }
 
        }
        answer = String.valueOf(arr);
 
        return answer;
    }
}
cs

 

코드를 짜는 와중 공백을 고려하지못해 실패도 겪으며 코딩했다. 완성한 것 속에는 꼭 많은 시도들이 숨어있는 것 같아서 겸손할 수 있었던 것 같다.

 

 

금일도 재미있고 유익한 문제의 연속이었고 12시 전에 끝낸 것이 처음이라서 정말 기쁘다.

체육복도, 또 하나의 문제도 이렇게 하루 안에 마무리할 수 있다는 것이 꿈만 같아서 현실감이 잘 느껴지지않는다.

 

보잘 것 없을지도 모르겠지만 스스로에겐 참 고마운 날인 듯 하다.