프로그래머스 Lv2 JadenCase 문자열 만들기

weonest·2023년 4월 9일
0

coding-test

목록 보기
3/36

문제 설명

JadenCase란 모든 단어의 첫 문자가 대문자이고, 그 외의 알파벳은 소문자인 문자열입니다. 단, 첫 문자가 알파벳이 아닐 때에는 이어지는 알파벳은 소문자로 쓰면 됩니다. (첫 번째 입출력 예 참고)문자열 s가 주어졌을 때, s를 JadenCase로 바꾼 문자열을 리턴하는 함수, solution을 완성해주세요.

제한 조건

  • s는 길이 1 이상 200 이하인 문자열입니다.
  • s는 알파벳과 숫자, 공백문자(" ")로 이루어져 있습니다.
    • 숫자는 단어의 첫 문자로만 나옵니다.
    • 숫자로만 이루어진 단어는 없습니다.
    • 공백문자가 연속해서 나올 수 있습니다.

입출력 예

sreturn
"3people unFollowed me""3people Unfollowed Me"
"for the last week""For The Last Week"

나의 풀이

이번 문제는 생각의 전환이 필요했던 문제였다고 생각한다. 알파벳 문자열만 보면 습관적으로 아스키 코드를 찾게되는 와타시…

우선 나의 접근법은 이러했다.

  1. 모든 문자열을 소문자로 치환 후 split한다
  2. 첫 번째 글자가 정수 96 (소문자 a의 아스키) 을 넘는다면 -32
  3. 그 이후의 글자가 정수 96 보다 작다면 +32
  4. 마지막에 공백 추가

코드로 보면 다음과 같다.

import java.util.Arrays;
import java.util.Locale;

class Solution {
    public String solution(String s) {

        StringBuilder answer = new StringBuilder();

        String[] arr = s.toLowerCase().split(" ");

        System.out.println("arr = " + Arrays.toString(arr));

        for (int i = 0; i < arr.length; i++) {
            if (arr[i].charAt(0) > 96) {
                int tmp = arr[i].charAt(0) - 32;
                char c = (char) tmp;
                answer.append(c);
            } else {
                answer.append(arr[i].charAt(0));

            }

            for (int j = 1; j < arr[i].length(); j++) {
                answer.append(arr[i].charAt(j));
                if (j == arr[i].length() - 1) {
                    answer.append(" ");
                }
            }
        }

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

여차저차 테스트 코드는 통과하였지만, 그 이후의 테스트 케이스들은 통과하지 못했다. 몇 가지의 테스트 케이스들을 검증한 결과 “a (공백)(공백)(공백) b (공백)(공백)(공백) c”와 같이 여러 개의 공백이 들어오는 경우를 처리하지 못한 것이다!

또한, 아스키로 비교하는 것보다 형변환을 통한 비교가 빠르지 않나 생각하여 찾아보았더니 char 자료형에 + “”을 해주면 쉽게 String 자료형으로 변환이 되는 것을 확인했다! (String.valueOf 쓰고 있었는데..)

그렇게 수정한 코드는 다음과 같다.

import java.util.Arrays;
import java.util.Locale;

class Solution {
    public String solution(String str) {
        String s = str.toLowerCase();

        StringBuilder answer = new StringBuilder();

        String firstStr = s.charAt(0) + "";
        answer.append(firstStr.toUpperCase());

        for (int i = 1; i < s.length(); i++) {

            String cur = s.charAt(i) + "";
            System.out.println("cur = " + cur);

            if (cur.equals(" ")) {
                answer.append(" ");
            } else if (s.charAt(i - 1) == ' ') {
                answer.append(cur.toUpperCase());
            } else {
                answer.append(cur);
            }

        }
        System.out.println("answer.toString() = " + answer.toString());
        return answer.toString();
    }

    public static void main(String[] args) {
        Solution sol = new Solution();
        sol.solution("a   a   a   a ");
        // 무조건 공백은 하나만 남겨야 하는 건 줄
    }
}

위 코드에서도 몇 가지 시행착오가 있었는데, 위에서 예시를 들었던 “a (공백)(공백)(공백) b (공백)(공백)(공백) c” 문자열이 오면 “A(공백) B(공백) C(공백)” 과 같이 공백을 하나만 남겨야 한다고 생각했다. 하지만 이런 결과를 도출하는 코드를 제출했을 때 어김없이 실패가 나왔고, 모든 공백에 대해서 처리를 해주었더니 통과할 수 있었다.

역시 항상 느끼는 거지만 코딩테스트는 하나의 개념만을 가지고 풀기에는 너무나 비효율적이기 때문에 다양한 문제들을 풀며 여러가지 개념들을 익혀 적용시켜나가는 것이 이상적인 것 같다.

0개의 댓글