https://programmers.co.kr/learn/courses/30/lessons/12926
공백은 건너뛰고
글자면 대문자면 원래 글자에 + n 한게 'Z' 보다크면 -26 하고 소문자면 원래 글자에 +n 한게 'z'보다 크면 -26하면된다.(대소문자 따로 취급)
char[] 배열이 좋을까? 아니면 StringBuffer가 좋을까? 둘 다 해보자.
char배열 에 다 넣어놓고 하나씩 빼면서 확인
// 테스트코드
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class Quiz1_CaesarCipherTest {
Quiz1_CaesarCipher q;
@BeforeEach
void setUp() {
q = new Quiz1_CaesarCipher();
}
@Test
void test1() {
assertEquals(new String("BC"), q.solution(new String("AB"), 1));
}
@Test
void test2() {
assertEquals(new String("a"), q.solution(new String("z"), 1));
}
@Test
void test3() {
assertEquals(new String("e F d"), q.solution(new String("a B z"), 4));
}
}
//프로덕션코드
public class Quiz1_CaesarCipher {
public String solution(String s, int n) {
char[] charArray = new char[s.length()];
for (int i = 0; i < s.length(); i++) {
charArray[i] = s.charAt(i);
}
char[] newCharArray = new char[s.length()];
for (int i = 0; i < charArray.length; i++) {
newCharArray[i] = encrypt(charArray[i], n);
}
return new String(newCharArray);
}
char encrypt(char element, int n) {
if (element == ' ') {
return element;
}
int newElement = element + n;
if (newElement > 'z') {
newElement -= 26;
return (char) newElement;
}
if ('Z' < newElement && newElement < 'a') {
newElement -= 26;
return (char) newElement;
}
return (char) newElement;
}
}
// 히든테스트케이스 중에 통과 안되는 것들이 있네? 뭘 빠뜨렸을까?
// 아? 'Z' 가 57 이고 'a' 가 64 네? 범위를 저렇게 잡아놓으면 포함 안되는 경우들이 존재한다.
//프로덕션코드
public class Quiz1_CaesarCipher {
public String solution(String s, int n) {
char[] charArray = new char[s.length()];
for (int i = 0; i < s.length(); i++) {
charArray[i] = s.charAt(i);
}
char[] newCharArray = new char[s.length()];
for (int i = 0; i < charArray.length; i++) {
newCharArray[i] = encrypt(charArray[i], n);
}
return new String(newCharArray);
}
char encrypt(char element, int n) {
if (element == ' ') {
return element;
}
int newElement = element + n;
if ('z' < newElement) {
newElement -= 26;
return (char) newElement;
}
if (element <= 'Z') {
if ('Z' < newElement) {
newElement -= 26;
return (char) newElement;
}
}
return (char) newElement;
}
}
// 성공! 리팩토링!
public class Quiz1_CaesarCipher {
public String solution(String s, int n) {
char[] charArray = new char[s.length()];
convertStringToCharArray(s, charArray);
char[] newCharArray = new char[s.length()];
encryptCharArray(n, charArray, newCharArray);
return new String(newCharArray);
}
private void encryptCharArray(int n, char[] charArray, char[] newCharArray) {
for (int i = 0; i < charArray.length; i++) {
newCharArray[i] = encrypt(charArray[i], n);
}
}
private void convertStringToCharArray(String s, char[] charArray) {
for (int i = 0; i < s.length(); i++) {
charArray[i] = s.charAt(i);
}
}
char encrypt(char element, int n) {
if (elementIsSpace(element)) {
return element;
}
int newElement = element + n;
if (lowerLetterIsOverz(newElement)) {
newElement -= 26;
return (char) newElement;
}
if (elementIsUpperLetter(element)) {
if (upperLetterIsOverZ(newElement, 'Z')) {
newElement -= 26;
return (char) newElement;
}
}
return (char) newElement;
}
private boolean upperLetterIsOverZ(int newElement, int z) {
return z < newElement;
}
private boolean elementIsUpperLetter(char element) {
return element <= 'Z';
}
private boolean lowerLetterIsOverz(int newElement) {
return 'z' < newElement;
}
private boolean elementIsSpace(char element) {
return element == ' ';
}
}
// 성공!
이제 스트링버퍼로 풀어보자!
// 프로덕션코드
public class Quiz1_CaesarCipher_2 {
public String solution(String s, int n) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < s.length(); i++) {
sb.append(encrypt(s.charAt(i), n));
}
return new String(sb);
}
char encrypt(char element, int n) {
if (element == ' ') {
return element;
}
int newElement = element + n;
if (newElement > 'z') {
newElement -= 26;
return (char) newElement;
}
if (newElement <= 'Z') {
if (newElement > 'Z') {
newElement -= 26;
return (char) newElement;
}
}
return (char) newElement;
}
}
// 히든 테스트 케이스 실패! 이유가 뭘까?
// 논리는 똑같은데 StringBuffer를 다루면서 놓친 부분이 있는가보다.
// 아.. encrypt 메소드에서 if(newElement <= 'Z') 가 아니라 if(element <= 'Z') 이다.
// 프로덕션코드
public class Quiz1_CaesarCipher_2 {
public String solution(String s, int n) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < s.length(); i++) {
sb.append(encrypt(s.charAt(i), n));
}
return new String(sb);
}
char encrypt(char element, int n) {
if (element == ' ') {
return element;
}
int newElement = element + n;
if (newElement > 'z') {
newElement -= 26;
return (char) newElement;
}
if (element <= 'Z') {
if (newElement > 'Z') {
newElement -= 26;
return (char) newElement;
}
}
return (char) newElement;
}
}
// 성공!
'코딩테스트연습 > 프로그래머스' 카테고리의 다른 글
[프로그래머스 - JAVA] 같은 숫자는 싫어 (1) | 2021.12.13 |
---|---|
[프로그래머스 - JAVA] 이상한 문자 만들기 (0) | 2021.12.12 |
[프로그래머스 - JAVA] 나누어 떨어지는 숫자 배열 (0) | 2021.12.05 |
[프로그래머스 - JAVA] 실패율 (0) | 2021.12.03 |
[프로그래머스 - JAVA] 두 개 뽑아서 더하기 (0) | 2021.12.02 |