[프로그래머스/java] 시저 암호

리트리버J

·

2021. 1. 3. 00:31

728x90

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

 

<나의 풀이>

문제점 :

1. 다중 if else문으로 너무 복잡하다!

2. String → char[] → String 변환이 잦다.

 

* 해결 포인트 *

1. char + int = int가 되므로 (char)형변환이 필요하다.

2. 대소문자 각각 26개 단위로 끊어지므로 'z' / 'Z'가 넘을 때 -26을 해주어야 한다.

65~90 : A~Z

97~122 : a~z 

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
class Solution {
    public String solution(String s, int n) {
        char[] charArr = s.toCharArray();
        char[] newOne = new char[charArr.length];
        for(int i = 0; i<charArr.length; i++) {
            if(charArr[i] == ' ') {
                newOne[i] = ' ';
            }else {
                if(charArr[i] >= 'a' && charArr[i] <= 'z') {
                    if(charArr[i] + n > 'z')
                        newOne[i] = (char)(charArr[i] + n-26);
                    else
                        newOne[i] = (char)(charArr[i] + n);
                }
                else if(charArr[i] >= 'A' && charArr[i] <= 'Z'){
                    if(charArr[i] + n > 'Z')
                        newOne[i] = (char)(charArr[i] + n-26);
                    else
                        newOne[i] = (char)(charArr[i] + n);
                }
            }
        }
        return String.valueOf(newOne);
    }
}
cs

 

 

 

 

 

<사이트 풀이>

코드는 짧지만 소요 시간이 오히려 길었다.
*포인트*
1. Character 클래스의 isLowerCase() / isUpperCase() 이용
2. %연산자를 사용하여 나머지를 이용해 계산
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Solution {
    public String solution(String s, int n) {
        String result = "";
        for (int i = 0; i < s.length(); i++) {
            char ch = s.charAt(i);
            if (Character.isLowerCase(ch)) {
                ch = (char) ((ch - 'a' + n) % 26 + 'a');
            }else if (Character.isUpperCase(ch)) {
                ch = (char) ((ch - 'A' + n) % 26 + 'A');
            }
                result += ch;
        }
        return result;
    }
}
cs

 

<사이트 풀이 + 나의 코드 추가>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Solution {
    public String solution(String s, int n) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < s.length(); i++) {
            char ch = s.charAt(i);
            if (Character.isLowerCase(ch)) {
                ch = (char) ((ch - 'a' + n) % 26 + 'a');
            }else if (Character.isUpperCase(ch)) {
                ch = (char) ((ch - 'A' + n) % 26 + 'A');
            }
                sb.append(ch);
        }
        return sb.toString();
    }
}
cs

 

 

String에 +=연산자를 이용하였기 때문에 메모리 소모가 큰 것으로 판단하여,

StringBuffer클래스를 이용하여 조금 변형시켜주니 속도가 12.3ms => 0.12ms로 바뀌었다.

StringBuffer / StringBuilder 클래스를 활용해야겠다.

메모리 소모의 중요성을 느꼈다!!

출처: 프로그래머스 코딩 테스트 연습, 
https://programmers.co.kr/learn/challenges

728x90