Coding Test

[Java / Kotlin] 99 클럽 코딩 테스트 스터디 미들러 5일차 - JadenCase 문자열 만들기

SeungYong.Lee 2024. 7. 25. 14:54
반응형

 

[문제]

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

 

[제한 조건]

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

[입출력 예]

 

[풀이]

일단 문제를 살펴보면 결국 모든 문자가 소문자로 변경시켜 버리는 게 전제입니다.
모든 문자를 소문자로 변경시킨 뒤, 공백을 기준으로 단어들을 구분하여 각 단어의 첫 글자가 알파벳이면 대문자로, 그게 아니라면 그대로 단어를 반환하면 됩니다.

 

먼저 코틀린 풀이입니다.

처음에는 아래와 같이 풀었으나 메모리 시간 초과에 걸렸습니다.

fun solution1(s: String): String {
    val arr = s.split(" ")
    val res = mutableListOf<String>()
    arr.forEach {
        val temp = it
        val first = temp.first()
        if (first.isLetter()) {
            res.add(temp.lowercase().replaceFirst(first, first.uppercaseChar()))
        } else {
            res.add(temp.lowercase())
        }
    }
    return res.joinToString(" ")
}

먼저 소문자로 전체를 치환하지 않고, 문자 단위로 잘라서 조건에 따라 replace, 소문자 변환 과정을 거쳤고, 또 그 변환된 값을 새로운 리스트에 넣고 String 처리하다 보니 시간 초과에 걸린 것으로 보입니다. 불필요하게 로직이 장황해진 결과네요..

 

또한 replace로 첫 글자를 대문자 처리하는 과정 자체가 비효율적이었습니다.

코틀린에 capitalize()라는 함수가 존재했습니다.

해당 함수의 내용을 보자면..

public fun String.capitalize(locale: Locale): String {
    if (isNotEmpty()) {
        val firstChar = this[0]
        if (firstChar.isLowerCase()) {
            return buildString {
                val titleChar = firstChar.titlecaseChar()
                if (titleChar != firstChar.uppercaseChar()) {
                    append(titleChar)
                } else {
                    append(this@capitalize.substring(0, 1).uppercase(locale))
                }
                append(this@capitalize.substring(1))
            }
        }
    }
    return this
}

네, 단어의 앞 첫 글자를 대문자로 만들어주는 String 확장 함수입니다.

해당 함수의 존재를 뒤늦게 파악하고 전체 문자열을 소문자 처리 -> split -> capitalize 과정을 거치면 정답을 얻을 수 있었습니다.

fun solution2(s: String): String = 
    s.lowercase().split(" ").joinToString(" "){ it.capitalize(Locale.ROOT) }

확실히 다양한 함수 사용 경험 중요성을 느끼게 한 문제였습니다.

 

이번엔 자바 풀이입니다.

자바 또한 최대한 시간을 고려하여 StringBuilder에 계산된 결과 값을 추가하는 방식으로 진행했습니다.

public String solution(String s) {
    StringBuilder answer = new StringBuilder();
    String[] sp = s.split(" ");

    for (String string : sp) {
        if (string.isEmpty()) answer.append(" ");
        else {
            answer.append(string.substring(0, 1).toUpperCase());
            answer.append(string.substring(1).toLowerCase());
            answer.append(" ");
        }
    }

    if(s.charAt(s.length() - 1) == ' ') return answer.toString();
    return answer.substring(0, answer.length() - 1);
}

공백을 기준으로 문자열을 나눴고, 각 String을 조회하면서 조건에 맞게 대문자 처리 및 공백 추가를 진행해 줬습니다.

마지막에는 다시 공백 유무를 체크하여 불필요한 부분을 잘라내는 처리를 진행했습니다.

자바에서는 subString을 활용해서 앞부분, 나머지 부분을 구분했습니다.

반응형