[문제]
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을 활용해서 앞부분, 나머지 부분을 구분했습니다.