이상한 문자 만들기

문제 링크 : https://school.programmers.co.kr/learn/courses/30/lessons/12930

문제 풀이에 앞서, 이 문제는 JadenCase 문자열 만들기에서 풀었던 문제와 매우 유사하다. 해당 문제를 풀면서 배웠던 내용을 응용해서 쉽게 풀 수 있었다.

문제에 대한 내용

문제 설명

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

제한 조건

  • 문자열 전체의 짝/홀수 인덱스가 아니라, 단어(공백을 기준)별로 짝/홀수 인덱스를 판단해야합니다.
  • 첫 번째 글자는 0번째 인덱스로 보아 짝수번째 알파벳으로 처리해야 합니다.

입출력 예

s return
“try hello world” “TrY HeLlO WoRlD”

입출력 예 설명

“try hello world”는 세 단어 “try”, “hello”, “world”로 구성되어 있습니다. 각 단어의 짝수번째 문자를 대문자로, 홀수번째 문자를 소문자로 바꾸면 “TrY”, “HeLlO”, “WoRlD”입니다. 따라서 “TrY HeLlO WoRlD” 를 리턴합니다.

접근 방식

  1. 공백을 기준으로 만약 현재가 공백이라면, 다음은 무조건 대문자로 변환해야 한다. (단어의 처음이라는 뜻, 0번 인덱스)
  2. 각 단어별로 인덱스가 따로 설정된다.
  3. 인덱스르 카운트 하는 변수를 설정한다.
  4. 따라서 현재 공백이라면, 인덱스를 0으로 초기화하고 그렇지 않다면, 카운트를 +1 한다.
  5. 카운트르가 2의 배수인지 유무를 파악(짝수 인덱스인지 파악)해서, 배수라면 대문자로 변환해서 문자열에 추가한다.
  6. 결과를 리턴한다.

결과

소스 코드

class Solution {
    public String solution(String s) {
        StringBuilder answer = new StringBuilder();
        s = s.toLowerCase();
        int cnt = 0;
        for (String tmp:s.split("")){
            if (cnt % 2 == 0) answer.append(tmp.toUpperCase());
            else answer.append(tmp);
            cnt = tmp.equals(" ") ? 0 : cnt + 1;
        }
        return answer.toString();
    }
}

결과 이미지

alt text

다른 접근 방식

기본적으로 대부분, 거의 비슷한 방식을 사용하고 있었다. 그렇게 여러 코드를 살펴 보다 거의 비슷한 로직이지만 성능상으로 결과가 2~10배 정도 차이가 나는 코드를 발견했다.

class Solution {
  public String solution(String s) {
        char[] chars = s.toCharArray();
        int idx = 0;

        for (int i = 0; i < chars.length; i++) {
            if (chars[i] == ' ') idx = 0;
            else chars[i] = (idx++ % 2 == 0 ? Character.toUpperCase(chars[i]) : Character.toLowerCase(chars[i]));
        }

        return String.valueOf(chars);
  }
}

기본적으로 idx라는 변수를 이용, 공백인경우 초기화 이 두 가지 핵심은 동일하다.

하지만, 이 코드에서는 문자열 배열, 문자열 비교가 아닌 문자 배열, 문자 비교를 하고 있다.

따라서 문자로 비교하는 것이 성능이 더 좋게 나온 것이다.

알게 된 점

문제에서 요구하는 사항이 타이트하거나 성능이 요구되는 경우에는 문자를 이용하는 것을 고려해 봐야겠다.