코딩테스트연습/프로그래머스

[프로그래머스 - JAVA] 이상한 문자 만들기

:)jun 2021. 12. 12. 19:46

https://programmers.co.kr/learn/courses/30/lessons/12930

 

코딩테스트 연습 - 이상한 문자 만들기

문자열 s는 한 개 이상의 단어로 구성되어 있습니다. 각 단어는 하나 이상의 공백문자로 구분되어 있습니다. 각 단어의 짝수번째 알파벳은 대문자로, 홀수번째 알파벳은 소문자로 바꾼 문자열을

programmers.co.kr

//테스트코드

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.*;

class Quiz1_MakingWeirdWordTest {

    Quiz1_MakingWeirdWord q;

    @BeforeEach
    void setUp() {
        q = new Quiz1_MakingWeirdWord();
    }

    @Test
    void 한글자() {
        assertEquals("A", q.solution("a"));
    }

    @Test
    void 한단어() {
        assertEquals("TrY", q.solution("try"));
    }

    @Test
    void 세단어() {
        assertEquals("TrY HeLlO WoRlD", q.solution("try hello world"));

    }
}

//프로덕션코드

import java.util.Locale;

public class Quiz1_MakingWeirdWord {

    public String solution(String s) {

        if (s.length() == 1) {
            return s.toUpperCase();
        }

        String[] words = s.split(" ");
        String[] weirdWords = new String[words.length];

        for (int j = 0; j < words.length; j++) {
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < words[j].length(); i++) {
                if (i % 2 == 0) {
                    sb.append(words[j].substring(i, i + 1).toUpperCase());
                }

                if (i % 2 == 1) {
                    sb.append(words[j].substring(i, i + 1).toLowerCase());
                }
            }

            weirdWords[j] = sb.toString();

        }

        String answer = "";
        for (int i = 0; i < weirdWords.length; i++) {
            answer += weirdWords[i] + " ";
        }


        return answer.substring(0, answer.length() - 1);
    }

}


// 히든 테스트 케이스 실패... 놓친부분이 어딜까? 
// 정말 모르겠는데... 의심스러운 부분은 1글자, 1단어 일때인데 다 통과를 했고 그 다음은 범위에 대한 의심인데..
// 아.. 단어 사이에 공백이 한개이상 주어지는구나

//프로덕션코드


        if (s.length() == 1) {
            return s.toUpperCase();
        }

        String[] words = s.split(" ");
        String[] weirdWords = new String[words.length];

        for (int j = 0; j < words.length; j++) {
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < words[j].length(); i++) {
                sb.append(makeWeirdWord(words, j, i));
            }

            weirdWords[j] = sb.toString();

        }

        String answer = "";
        for (int i = 0; i < weirdWords.length; i++) {
            answer += (" " + weirdWords[i]);
        }


        return answer.substring(1);
    }

    private String makeWeirdWord(String[] words, int j, int i) {
     
        if (words[j].substring(i, i + 1) == " ") {
            return " ";
        }
        
        if (i % 2 == 0) {
            return words[j].substring(i, i + 1).toUpperCase();
        }

        
        return words[j].substring(i, i + 1).toLowerCase();

    }

}

// 공백일때 대문자,소문자 바꾸는 쪽으로 넘어가지말고 바로 공백리턴해줬다.
// 결과는 실패. split(" ")이 어떻게 넘어가는지 테스트 코드 짜고 확인해보자.

//테스트코드
   @Test
    void 공백세번(){
        assertEquals("TrY   HeLlO  WoRlD", q.solution("try   hello  world"));
    }
    
// 이건 성공! 어떤 부분이 문제일까? 게다가 새로 추가해준 부분 없어도 정상적으로 작동하네?
// 공백에다 toUpperCase(), toLowerCase()해줘도 문제는 없고 다시 공백으로 나오나보다.
// 그리고 split(" ") 이렇게 하면 (단어+3개의 공백+단어)가 (단어 , "", "" , 단어) 로 나뉘네.
// 공백세번 케이스에서는 answer만들때 빈칸이 갯수만큼 들어가니까 다시 맞는거고.
// 그래서 난 어디서 틀렸을까? 질문 찬스 써야겠다.

// split(" ",-1) 처럼 -1 넣으면 성공! why?

 

JAVA API

1. limit 값이 양수 N이라고 하면 N-1번 나눠져서 최대 N개의 배열이 생성된다.

2. limit 값이 음수라고 하면 가능한 모든 것들을 나눠서 배열이 생성된다.

3. limit 값이 0이면 가능한 모든 것들을 나눠서 배열이 생성되는데 마지막 빈 문자열은 버려진다.

 

그럼 limit값 안써줬을 때랑 뭐가 다르지? -> 안써주면 limit 0과 같다.

그럼 마지막 빈 문자열을 버렸기 때문에 자꾸 틀렸던거네!

JAVA API

 

//테스트코드

    @Test
    void 마지막문자열공백(){
        assertEquals("TrY     HeLlO  WoRlD   ", q.solution("try     hello  world   "));
    }
    
    
// 그러네요. 문제가 너무 불친절했다!
// 그래도 덕분에 split메소드 자세히 알 수 있어서 좋았다! 리팩토링하고 마무리하자!


//프로덕션코드 
public class Quiz1_MakingWeirdWord {
    public String solution(String s) {

        String[] words = s.split(" ", -1);

        String[] weirdWords = new String[words.length];
        setWeirdWords(words, weirdWords);

        String answer = "";
        return setAnswer(weirdWords, answer).substring(1);

    }

    private void setWeirdWords(String[] words, String[] weirdWords) {
        for (int j = 0; j < words.length; j++) {
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < words[j].length(); i++) {
                sb.append(setWeirdWordByCharacterUnit(words, j, i));
            }
            weirdWords[j] = sb.toString();
        }
    }

    private String setAnswer(String[] weirdWords, String answer) {
        for (int i = 0; i < weirdWords.length; i++) {
            answer += (" " + weirdWords[i]);
        }
        return answer;
    }

    private String setWeirdWordByCharacterUnit(String[] words, int j, int i) {
        if (i % 2 == 0) {
            return words[j].substring(i, i + 1).toUpperCase();
        }
        return words[j].substring(i, i + 1).toLowerCase();
    }
}


// 음... 기능단위로 잘라야하는데 내일은 좀 더 신경써서 잘라보자. 딱 봤을때 눈에 한번에 안들어오는데?
// 면접때문에 미뤄놨던 클린코드 책 다시 편하게 쭉 보자!