코딩 테스트

[HackerRank] Caesar Cipher

juble 2024. 10. 30. 13:59

Problem


Julius Caesar protected his confidential information by encrypting it using a cipher. Caesar's cipher shifts each letter by a number of letters. If the shift takes you past the end of the alphabet, just rotate back to the front of the alphabet. In the case of a rotation by 3, w, x, y and z would map to z, a, b and c.

Original alphabet:      abcdefghijklmnopqrstuvwxyz
Alphabet rotated +3:    defghijklmnopqrstuvwxyzabc

 

Example
s = There's-a-starman-waiting-in-the-sky
k = 3

The alphabet is rotated by 3, matching the mapping above. The encrypted string is Wkhuh'v-d-vwdupdq-zdlwlqj-lq-wkh-vnb.

 

Note: The cipher only encrypts letters; symbols, such as -, remain unencrypted.

 

Function Description

Complete the caesarCipher function in the editor below.

caesarCipher has the following parameter(s):

  • string s: cleartext
  • int k: the alphabet rotation factor

Returns

  • string: the encrypted string

Input Format

The first line contains the integer, n, the length of the unencrypted string.
The second line contains the unencrypted string, s.
The third line contains k, the number of letters to rotate the alphabet by.

Constraints

1 ≤ n ≤ 100
0 ≤ k ≤ 100
s is a valid ASCII string without any spaces.

Sample Input

11
middle-Outz
2

Sample Output

okffng-Qwvb

Explanation

Original alphabet:      abcdefghijklmnopqrstuvwxyz
Alphabet rotated +2:    cdefghijklmnopqrstuvwxyzab

m -> o
i -> k
d -> f
d -> f
l -> n
e -> g
-    -
O -> Q
u -> w
t -> v
z -> b

Julius Caesar는 기밀 정보를 암호화하여 보호하기 위해 암호를 사용했습니다. Caesar 암호는 각 글자를 일정한 수만큼 밀어내는 방식입니다. 알파벳의 끝을 넘어가게 되면 다시 처음으로 돌아갑니다. 예를 들어, 3만큼 밀어내기를 할 때, w, x, y, z는 각각 z, a, b, c로 변환됩니다.

 

예시

  • 원본 알파벳: abcdefghijklmnopqrstuvwxyz
  • 알파벳을 +3만큼 회전: defghijklmnopqrstuvwxyzabc

예시 입력

s = "There's-a-starman-waiting-in-the-sky"
k = 3

알파벳이 3만큼 회전하게 되면 w -> z, x -> a, y -> b, z -> c와 같이 매핑됩니다.
암호화된 문자열은 "Wkhuh'v-d-vwdupdq-zdlwlqj-lq-wkh-vnb"가 됩니다.

 

주의: 암호는 문자만 변환하며, -와 같은 특수 문자는 변환되지 않습니다.


함수 설명

caesarCipher 함수를 완성하세요.

  • 매개변수
    • s: 평문(암호화 전 문자열)
    • k: 알파벳 회전 수
  • 반환값
    • 암호화된 문자열을 반환합니다.

입력 형식

  • 첫 번째 줄에 문자열의 길이 n이 주어집니다.
  • 두 번째 줄에 암호화되지 않은 문자열 s가 주어집니다.
  • 세 번째 줄에 알파벳 회전 수 k가 주어집니다.

제약 조건

  • 1≤n≤1001 \leq n \leq 100
  • 0≤k≤1000 \leq k \leq 100
  • s는 공백이 없는 유효한 ASCII 문자열입니다.
728x90

 

Solution


public static String caesarCipher(String s, int k) {
    // 회전을 알파벳 범위(26) 내로 조절
    k = k % 26;
    StringBuilder encrypted = new StringBuilder();

    for (char c : s.toCharArray()) {
        if (Character.isLetter(c)) {
            char base = Character.isUpperCase(c) ? 'A' : 'a';
            // 밀어내기 연산 수행
            char shifted = (char) (base + (c - base + k) % 26);
            encrypted.append(shifted);
        } else {
            // 문자가 아닐 경우 그대로 추가
            encrypted.append(c);
        }
    }

    return encrypted.toString();
}

 

이 함수는 주어진 문자열의 각 문자를 검사하여 알파벳이면 회전 수만큼 밀어내기 연산을 수행하고, 알파벳이 아니면 그대로 추가하는 방식으로 암호화된 문자열을 생성합니다.


1. StringBuilder란?

  • StringBuilder는 String 객체를 생성하고 수정할 때 사용되는 클래스입니다. String은 불변(immutable) 객체이므로, 문자열을 변경할 때마다 새로운 객체가 생성됩니다. 반면 StringBuilder는 기존 객체에 직접 변경을 가해 성능 면에서 유리하며, 문자열을 반복적으로 추가하거나 수정할 때 효율적입니다.
  • 언제 사용하는가?
    • 반복문 안에서 문자열을 변경하거나 여러 문자열을 이어 붙여야 할 때 StringBuilder를 사용하면 효율적입니다.

2. toCharArray()

  • toCharArray()는 String 객체를 char 배열로 변환하는 메서드입니다. 이렇게 하면 문자열의 각 문자를 하나씩 접근할 수 있어 반복문에서 개별 문자에 대해 연산을 수행하기 좋습니다.
  • 예시:
String str = "Hello"; 
char[] chars = str.toCharArray(); // 결과: ['H', 'e', 'l', 'l', 'o']
 

3. Character.isLetter(c)

  • Character.isLetter(c)는 char 값이 알파벳 문자(영문자)인지 확인합니다. true 또는 false를 반환하며, 문자가 알파벳이 아니면 이 조건을 통과하지 않아 암호화 대상에서 제외됩니다.
  • 예시:
Character.isLetter('A'); // 결과: true 
Character.isLetter('1'); // 결과: false

 

4. Character.isUpperCase(c)

  • Character.isUpperCase(c)는 특정 문자가 대문자인지 여부를 확인하는 메서드입니다. true 또는 false를 반환하며, 이 코드에서는 대문자와 소문자를 구분해 처리하기 위해 사용됩니다.
  • 예시:
 
Character.isUpperCase('A'); // 결과: true 
Character.isUpperCase('a'); // 결과: false

 

 

5. char shifted = (char) (base + (c - base + k) % 26); 

  • 이 부분은 Caesar Cipher의 핵심 연산으로, 문자를 k만큼 밀어내어 새로운 문자를 만드는 과정입니다.
    • base: 문자가 대문자인지 소문자인지에 따라 'A' 또는 'a'로 설정합니다. 이는 각 알파벳의 ASCII 코드에서 시작하는 값을 의미합니다.
    • (c - base): 현재 문자의 위치를 0부터 시작하는 알파벳 인덱스로 변환합니다. 예를 들어, A는 0, B는 1로 변환됩니다.
    • (c - base + k) % 26: 현재 위치에서 k만큼 회전한 새로운 위치를 구합니다. % 26은 알파벳 범위를 넘으면 처음부터 시작하게 하는 역할을 합니다.
    • base + (c - base + k) % 26: 계산된 인덱스 값을 다시 문자로 변환합니다.
  • 예를 들어 c = 'd'이고 k = 3인 경우:
    • base는 'a'
    • (c - base) = (100 - 97) = 3 // d는 알파벳에서 세 번째 위치
    • (3 + 3) % 26 = 6
    • base + 6 = 97 + 6 = 103으로 최종 결과는 g

6. encrypted.append(shifted)

  • StringBuilder 객체 encrypted에 새로운 문자 shifted를 추가하는 메서드입니다. append() 메서드를 통해 StringBuilder에 문자를 이어 붙이며, 최종 암호화된 문자열이 완성됩니다.
  • 예시:
StringBuilder sb = new StringBuilder("Hello"); 
sb.append('!'); // 결과: "Hello!"
 

728x90
반응형

'코딩 테스트' 카테고리의 다른 글

[HackerRank] Grid Challenge  (1) 2024.10.31
[HackerRank] Palindrome Index  (0) 2024.10.30
[HackerRank] Tower Breakers  (3) 2024.10.30
[Codility] MissingInteger  (0) 2024.10.04
[HackerRank] Zig Zag Sequence  (2) 2024.10.04