본문 바로가기
알고리즘 스터디/프로그래머스 스킬체크 레벨 1(끝)

[프로그래머스 스킬체크 레벨 1] 시저 암호 문제 풀이 및 설명 - 자바[Java]

by 레일라오리덕 2020. 5. 19.
728x90

https://programmers.co.kr/

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

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이하인 자연수입니다.

 

결괏값 예시

 

s n result
"A" 1 "BC"
"z" 1 "a"
"a B z" 4 "e F d"

 

기본 제공 틀

 

class Solution {
    public String solution(String s, int n) {
        String answer = "";
        return answer;
    }
}

 

풀이 [Java]

 

이 문제는 얼핏보면 간단할 수 있는데, 디테일하게 신경써줘야 할 부분이 많은 문제이다.

처음에는 문제 접근방식을 Array를 한바퀴 돌면서 가장 작은 수를 temp에 넣고 해당 숫자를 카피된 array에서 찾아서 삭제하는 방법을 구현하려다가, 문득 저번에 아스키코드를 사용하여 풀었던 문제가 생각이 나서 노선을 바꿔 풀어보았다.

역시 그 방법으로 풀어보다보니 새롭게 풀이해나가는 방법을 하나 터득할 수 있었다.

이전에 풀었던 이상한 문자에서 착안하여 문제를 풀어보았다. (아래 링크 참고)

https://leylaoriduck.tistory.com/17

 

[프로그래머스 스킬체크 레벨 1] 이상한 문자 만들기 문제 풀이 및 설명 - 자바[Java]

https://programmers.co.kr/ 프로그래머스 코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요. pr

leylaoriduck.tistory.com

해당 for문은 int값을 돌리는 것이 아니기 때문에 새로운 버전의 for문을 사용하였다.

입력받은 s라는 배열의 char를 돌면서 char가 공백인 경우는 공백을 answer에 넣어주었는데, 이 부분은 이상한 문자 만들기에서 사용했던 방법과 동일하다.

그 외에는 두 가지 가능성이 있는데, 소문자가 입력되어있을 확률, 그리고 대문자가 입력되어있을 확률로 2가지로 나누어진다.

이 때에, 소문자 값이 입력되어있으면, 해당 소문자 값에 추가할 값 n을 더해주고 다시 a값을 빼준 후, 26으로 나누어준다.

이렇게 복잡하게 값을 구하는 경우는, n값에 z를 추가하게 된다면 아스키코드의 a~z값에서 벗어나게 되기때문이다.

예를 들어, 들어온 값이 z이고 추가할 값이 문제에서 보다시피 1이게 되면, 122인 z의 값에서 추가된 값이 나오므로, 범위를 벗어나게된다.

그래서 123에서 소문자 a값을 다시 빼주고, 즉, 123-97 = 26 다시 26으로 나누어주게 되면, 0이라는 나머지 값이 나오게 되는데, 이에 97을 다시 더해준 후, char형으로 변환하게되면, 원하는 값은 a가 나오게 된다.


아주 쉽게 다시 설명하자면,

122인 z를 예를 들어 보면, 122+1은 소문자 아스키코드 값의 범주에서 벗어나게된다.

그래서 123이라는 숫자에서 범주의 가장 첫번째 값인 97을 빼주고, 그 값을 26으로 나눠준다.

여기서 26으로 나눠준 몫을 구하는 이유는, 소문자는 총 26개로 이루어져있기에, 26으로 나누어줬을때에, 알파벳중에 몇번째에 위치해 있는 값인지를 알아낼 수 있다. 그래서, 26으로 나누어준 값이 0인 경우, 다시 a를 더해주면 소문자 a가 나오게 되는 것이고, 몫이 1인 경우는, b, 몫이 2인 경우는 c...이런 식으로 값을 구하게 되는 것이다.

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);
                }
            }
            return answer;
        }
    }

 

채점 결과 [Java]

 

728x90

댓글