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

Lee·2023년 4월 5일
0

알고리즘

목록 보기
7/34
post-thumbnail

문제 출처

문제 출처 : 이상한 문자 만들기

문제 이해하기

  • 문제를 조금 더 쉽게 풀어서 작성해 보면, 공백문자로 구분되어 있는 단어들 입력으로 들어온다
  • 각 단어의 짝수번째는 대문자, 홀수번째는 소문자로 변환 (공백 해당 X)
  • 각 단어별로 대/소문자 치환 기준은 인덱스 값을 기준으로 나눈다.

주요 조건 이해하기 ⭐️

문제에 주어진 입출력 단어를 조금 더 쉽게 만들어서 위 문제를 이해해 보면
try라는 문자열이 들어왔을 때, t -> 인덱스 값은 0이므로 대문자, r -> 인덱스 값은 1이므로 소문자, y -> 인덱스 값은 2이므로 대문자이다. 최종적으로 변환시켜보면 TrY라는 값을 얻을 수 있다.

지금까지 이해한 내용을 바탕으로 규칙을 찾았을 때 아래와 같은 순서로 코드를 작성할 것이다.

  1. 입력으로 들어온 문자열을 공백 기준으로 분리한다.
  2. 해당 단어들을 문자 하나하나씩 순회하면서 대/소문자로 변환한다.
  3. 최종적으로 변환이 완료되면 이를 결과로 출력한다.

이를 바탕으로 스켈레톤 코드를 작성했을 땐 아래와 같은 형태로 나오게 되는데, 여기서 하나의 문제가 있다.
문제에 나와있는 테스트 케이스만 돌려봤을 땐 정상적으로 통과는 가능하겠지만, 실제로 제출할 경우 특정 테스트 케이스에 실패하는 경우가 발생한다.

	public String solution(String s) {

		// 공백을 기준으로 분리한다.
		String[] array = s.split(" ");

		// 공백을 기준으로 분리한 단어 하나 하나씩 접근
		for (int i = 0; i < array.length; i++) {

			// 각 단어에 인덱스를 순화하면서 대/소문자 변환
			for (int j = 0; j < array[i].length(); j++) {
				if (j % 2 == 0) {
					// 대문자 치환 로직
				} else {
					// 소문자 치환 로직
				}
			}
		}

		return "";
	}

곰곰이 생각해 보면 아래에 작성해놓은 2가지 이유로 인해 특정 테스트 케이스를 통과하지 못했다고 생각했다.

  • 공백 문자가 연속적으로 올 경우
  • 문자열에 시작과 끝에 공백 문자가 존재할 경우

다시 이해한 내용을 바탕으로 규칙을 찾았을 때 아래와 같은 순서로 코드를 작성하였다.

  • 입력으로 들어온 문자열을 전체 대문자로 변경한다.
  • 문자열 s의 길이만큼 순회하면서 해당 문자열이 공백인 경우와 공백이 아닌 경우로 나눈다.
  • 공백이 아닌 경우는 문자열이라는 뜻이기 때문에 해당 문자열의 홀수인 경우만 체크한 후 소문자로 변경한다.
	public String solution(String s) {

		// for문에서 연산에 횟수를 줄이기 위해 입력으로 들어온 문자열을 대문자로 치환
		// 이때 소문자로 치환해도 상관 없음
		s = s.toUpperCase();

		// 결과를 담을 StringBuilder 타입의 변수 선언
		StringBuilder sb = new StringBuilder();

		// 단어의 인덱스값을 저장하는 변수
		int idx = 0;

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

			// 공백이 아닌 경우
			if (s.charAt(i) != ' ') {
				
				// 홀수인 경우 소문자로 치환시켜준다.
				// 작업이 끝나면 해당 단어의 인덱스 값을 증가시킨다.
				if (idx % 2 == 1) {
					sb.append((char) (s.charAt(i) + 32));
					idx++;
				} else {
					// 짝수인 경우 해당 문자열을 그대로 넣어준다.
					// 작업이 끝나면 해당 단어의 인덱스 값을 증가시킨다.
					sb.append(s.charAt(i));
					idx++;
				}
			} else { // 공백인 경우
				idx = 0; // 다음에 만날 단어의 인덱스를 저장하기 위해 지금까지 저장하고 있던 idx값을 초기화 시켜준다.
				sb.append(" "); // 결과를 담을 변수에 공백을 그대로 넣어준다.
			}
		}

		return sb.toString();
	}

최종 소스 파일

class Solution {
    public String solution(String s) {
		s = s.toUpperCase();
		StringBuilder sb = new StringBuilder();

		int idx = 0;

		for (int i = 0; i < s.length(); i++) {
			if (s.charAt(i) != ' ') {
				if (idx % 2 == 1) {
					sb.append((char) (s.charAt(i) + 32));
					idx++;
				} else {
					sb.append(s.charAt(i));
					idx++;
				}
			} else {
				idx = 0;
				sb.append(" ");
			}
		}

		return sb.toString();
	}
}

다른 풀이

  • 반복문을 순회하면서 처리하는 일은 동일하지만 내장 함수를 사용함으로써 코드의 양을 줄일 수 있다.
  • 삼항 연산자를 통해 분기 처리 로직 또한 줄일 수 있다.
  • 삼항 연산자는 코드 한 줄로 가독성을 챙길 수 있으며, 한 줄로 처리하기 복잡할 경우에는 if/else를 사용하는 게 낫다.
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;
  }
}

0개의 댓글