코딩테스트/HackerRank

[HackerRank] Caesar Cipher 📌

주니어주니 2023. 4. 6. 17:02

 

 

문제 

 

입력받은 문자열s에서 k만큼 이동한 문자열대로 암호화하기

 

 

 

 

내 생각

 

아 이렇게 하면 되겠다 했는데 안풀렸다

 

내 생각으로는
 - 원래 알파벳 순서대로 들어있는 배열을 만들고, rotated된 빈 배열을 새로 만듦
 - 원래 알파벳 배열에서 k만큼 이동한게 rotated 된 배열 
(그래서 원래 배열에서 앞 k만큼을 떼서 뒤에다가 붙이려고 했다 ㅋ 머 잘라서 append를 해야되나 했는데 점점 복잡해져서 이게 맞나 함)

- charAt()으로 입력받은 문자열의 각 문자의 인덱스를 구하고, 그 인덱스에 해당하는 문자를 rotated 배열에서 찾음

이런식으로 하려고 했는데..... 안 됐다

 

 

 

다른 사람 풀이 (아스키코드 !!)

 

 

package hackerrank;

import java.util.Scanner;

public class CaesarCipher {

	public static void main(String[] args) {
		
		// 알파벳이 26자이고 k가 26보다 크더라도 그 안에서 돌아야 되니까 26으로 나눈 나머지가 k가 되게 함
		k = k%26;
		// 암호화된 문자열을 생성하기 위함
		StringBuilder sb = new StringBuilder();

		// 일단 문자열을 char 배열로 변환해서 거기서 char를 하나씩 뽑아
		for(char c : s.toCharArray()) {
			// 문자일 때만 암호화 
			if(Character.isLetter(c)) {
				// 문자 + k 만큼을 더함 -> k만큼 이동한 문자의 아스키코드값
				int ascii = c + k;
				// 근데 만약 k를 더한 이 ascii 정수값이 알파벳 문자의 범위를 넘어서면 거기서 알파벳 길이 26을 뺌 -> 알파벳 범위 내 순환
				if(Character.isLowerCase(c) && !Character.isLowerCase(ascii) || Character.isUpperCase(c) && !Character.isUpperCase(ascii)) {
					ascii -= 26;
				} 
				
				// ascii 코드값을 문자로 변환한 값을 sb 문자열에 추가
				sb.append((char)ascii);
				
			} else {
				// 문자가 아닐 때는 그냥 그대로 붙여줌 (특수문자)
				sb.append(c); 
			}
		}
		
		System.out.println("rotated : " + sb);
	}
}

 

 

와 원래 알파벳 배열, 새로 만든 배열 이런게 없어도 되네 ㅁㅊ ㅠ 

문자 하나씩 뽑아서 거기다가 k만큼을 더한게 k만큼 이동한 문자랑 똑같잖아 ㅠ 

이 생각을 왜 못했을까?

 

근데 궁금한 점 

 

- if(Character.isLowerCase(c) && !Character.isLowerCase(ascii) || Character.isUpperCase(c) && !Character.isUpperCase(ascii))

이 부분에서 소문자를 확인할 때는 !Character.isLetter(ascii) 가 되는데, 대문자를 확인할 때는 !Character.isLetter(ascii)를 쓰면 왜 틀린 케이스가 나오는거지? 

근데 암튼 isLowerCase(), isUpperCase()로 확인하는게 fail이 안나오고 유지보수 측면에서 좋다고 한다.....