[프로그래머스] 시저 암호-JAVA

말하는 감자·2022년 5월 11일
0

Programmers Level 1

목록 보기
17/66
post-thumbnail

프로그래머스 Level 1

🔒 시저 암호

📚 문제 설명

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


✅ 제한 사항

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

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

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

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


📖 입출력 예

snresult
"AB"1"BC"
"z"1"a"
"a B z"4"e F d"

🔨 첫번째 작성 코드

class Solution {
    public String solution(String s, int n) {
        String answer = "";
        
        char[] ch = s.toCharArray();
        
        for(char c : ch) {
            if(c != 32) {
                if(c == 90 || c == 122) c -= 26;
                c += n;
                answer += c;
            } else
                answer += " ";
        }
        
        return answer;
    }
}

테스트 케이스는 성공하였으나 채점은 실패한 코드...😥

아스키코드(ASCII)를 이용하여 구현하였다.

아스키코드가 32이면 공백이라서 answr에 공백을 추가했고
90(Z)이나 122(z)면 알파벳의 마지막 숫자이므로 -26을 하여 65(A)와 97(a)의 앞으로 가게 설정했다.
A/a보다 하나씩 더 앞으로 간 이유는 Z/z에 1을 더하면 A/a가 되니깐!

근데 왜 틀렸을꼬...? 🤔❓

질문하기에 방문해야지...😔

아! n이 너무 크면 알파벳 범위를 넘어버리는구나!!
그럼 초과하면 26을 빼줘야지!!


🔨 두번째 작성 코드

class Solution {
    public String solution(String s, int n) {
        String answer = "";
        
        char[] ch = s.toCharArray();
        
        for(char c : ch) {
            if(c != 32) {
                c += n;
                if((c >= 90 && c < 97) || c >= 122) c -= 26;
                answer += c;
            } else
                answer += " ";
        }
        
        return answer;
    }
}

뭐가 문제일까... 아스키코드를 버리고 풀어야하나...

감자는 아스키코드 표만 겁나 째려보다가

아! 소문자는 소문자로 대문자는 대문자로 루프가 돌아야하는데
저렇게 하면 대문자가 소문자인 상태로 끝나버린다!!

하고 유레카를 외쳤다!!

그래서 테스트 케이스를 더 추가!


🔑 세번째 작성 코드

class Solution {
    public String solution(String s, int n) {
        String answer = "";
        
        char[] ch = s.toCharArray();
        
        for(char c : ch) {
            if(c == 32) answer += " ";
            else {
                if(c <= 90) {
                    c += n;
                    if(c > 90) c -= 26;
                } else {
                    c += n;
                    if(c > 122) c -= 26;
                }
                answer += c;
            }
        }
        
        return answer;
    }
}

ㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠ드뎌 성공이로구나!!ㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠ

새로운 마음으로 하려고 로직도 삭제했다가 다시 작성했다.

조건문 파티가 되긴 했지만 대문자일 때와 소문자일 때를 구분해줬다.
대문자일 때는 Z, 소문자일 때는 z를 넘기면 -26을 해줌으로써 대소문자 각각 안에서 루프!!


🔓 다른 사람의 코드

class Solution {
        public String solution(String s, int n) {
            String answer = "";
            for(char ch : s.toCharArray()) {
                if(ch==' ') {
                    answer += ch;
                }else if(ch>='a'&& ch<='z'){
                    answer += (char)('a' + (ch+n-'a')%26);
                }else {
                    answer += (char)('A' + (ch+n-'A')%26);
                }
            }
            System.out.println(answer);
            return answer;
        }
    }

뭐야... 누가 이렇게 똑똑한 코드로 성공하래요...🥺 우쒸...!!

(A/a와 원래 문자의 차이 + 밀리는 수 n)을 26으로 나눈 나머지 = 루프를 돌고나서의 차이 (결과적으로 밀린 정도)인 것이다.


😰 느낀 점

방향은 잘 잡아놓고 길을 헤매버렸다.

그동안 술술 풀다가 반나절동안 전전긍긍하는 문제가 나오니깐 해결을 못하는 감자에게 화나면서도 오랜만에 화가 날 정도의 문제를 푸니깐 너무 반갑고 재밌었다.
좀 변태같지만 감자는 이런 스트레스를 좋아한다.😏😋

profile
나는 말하는 감자다

0개의 댓글