본문 바로가기
알고리즘

자바 - 프로그래머스 - 이상한 문자 만들기

by Won's log 2024. 4. 2.

프로그래머스 문제 '이상한 문자 만들기' 풀이 과정을 정리해 보았다.

 

😡 처음 구현한 코드

import java.io.IOException;
import java.util.Arrays;

public class Main {
    public static void main(String[] args) throws IOException {
        String s = "try hello world";
        String answer = "";
        char[] charS = s.toCharArray();
        String[] strS = new String[charS.length];

        // 짝수, 홀수 -> 대문자로 변환
        for (int i=0; i<charS.length; i++) {
            if (i % 2 == 0) {
                strS[i] = String.valueOf(charS[i]).toUpperCase();
            } else {
                strS[i] = String.valueOf(charS[i]);
            }
        }
        System.out.println("strS = " + Arrays.toString(strS));
    }
}

// strS = [T, r, Y,  , H, e, L, l, O,  , W, o, R, l, D]

 

해당 코드의 문제점은 '공백'을 기준으로 짝수와 홀수를 체크하지 않았다는 점이다.

 

여러 번의 시도 끝에 공백을 확인하는 방법으로 Boolean 타입을 사용해 보았다.

온갖 for, switch, if문을 사용해 보았더니... 코드의 가독성이 매우 좋지 않았고, 원하는 값도 제대로 나오지 않았기 때문이다.

 

 

🤓 풀이 설계

1. boolean을 사용하여 공백을 기준으로 짝홀수를 판단한다.
2. for문을 사용해서 각 문자별로 순회한다.
3. 먼저 공백일 경우, boolean은 true로 선언
4. boolean이 true일 경우, 대문자로 변환 / false일 경우, 소문자로 변환
5. 변환한 값을 StringBuilder로 append 한다.
6. 최종적인 변환이 끝나면 꼭 boolean 값을 반대로 값설정.

 

😎수정된 코드

import java.util.Arrays;

// 공백을 기준으로 짝홀수 확인 -> 대문자로 변환
class Solution {
    public String solution(String s) {
        StringBuilder answer = new StringBuilder();
        boolean isEven = true; // 시작은 짝수로 설정

        for (char ch : s.toCharArray()) {
            if (ch == ' ') {
                answer.append(ch); // 공백은 그대로
                isEven = true; // 공백을 만나면 다음 문자는 다시 짝수로 시작
            } else {
                if (isEven) {
                    answer.append(Character.toUpperCase(ch)); // 짝수번째 문자는 대문자로
                } else {
                    answer.append(Character.toLowerCase(ch)); // 홀수번째 문자는 소문자로
                }
                isEven = !isEven; // 짝수, 홀수를 토글
            }
        }

        return answer.toString();
    }
}

 

for (char ch : s.toCharArray()) 가 익숙하지 않은 분들을 위해 소개하자면 해당 for문은 향상된 for문(개선된 for 문)을 활용하였다.

아래 값과 동일한 결과를 가져오지만 보다 간단하게 적기 위해 사용하였다.

        for (int i = 0; i < s.length(); i++) {
            char ch = s.charAt(i);
            if (ch == ' ') {
                answer.append(ch); // 공백은 그대로 추가
                isEven = true; // 공백을 만나면 다음 문자는 다시 짝수로 시작
            } else {
                if (!Character.isLowerCase(ch)) {
                    ch = Character.toLowerCase(ch); // 소문자로 변환
                }
                if (isEven) {
                    answer.append(Character.toUpperCase(ch)); // 짝수번째 문자는 대문자로
                } else {
                    answer.append(ch); // 홀수번째 문자는 그대로
                }
                isEven = !isEven; // 짝수, 홀수를 토글
            }
        }

 

😯 다른 사람의 코드

class Solution {
  public String solution(String s) {

        String answer = "";
        int cnt = 0;
        String[] array = s.split("");

        for(String ss : array) {
            cnt = ss.contains(" ") ? 0 : cnt + 1;
            answer += cnt%2 == 0 ? ss.toLowerCase() : ss.toUpperCase(); 
        }
      return answer;
  }
}

일단 내가 잘 사용하지 않은 코드들이다 보니 한 줄 한 줄씩 이해를 해보았다.

 

배울 점은

1. 문자를 한 번에 배열로 쪼개서 생성하기 위해 split("")을 썼다는 점. 

2. 삼항 연산자를 사용하여 공백을 빠르게 확인한 것. 그리고 그것을 바로 cnt로 0 또는 1로 구분한 점

3. 구분한 cnt를 바탕으로 또다시 삼항 연산자를 사용하여 대소문자를 입력한 것

 

 

개인적으로 삼항 연산자를 잘 사용하지 않았는데 의식적으로 사용하는 습관을 가져야겠다.