간단하게 보이는 문제이지만 함정이 하나 있습니다. 입출력 예시에서는 드러나있지 않지만 공백 문자가 연속적으로 나올 수 있다는 점입니다. 따라서 아래 코드 처럼 단어 하나하나를 split으로 공백문자를 기준으로 나눈 다음에 join으로 다시 합치려고 하면 연속된 공백 문자를 처리할 수가 없습니다.
let sArray = s.split(separator: " ")
s.map { String($0) }.joined(separator: " ")
공백 문자를 여러개 처리하기 위해서는 결국 주어진 문자열을 한글자한글자 순차적으로 탐색하는 방법을 사용해야 합니다.
func solution(_ s:String) -> String {
// 결과를 저장할 문자열
var result = ""
// 해당 글자가 공백 이후 첫 글자인지
var isFirst = true
for c in s {
// 공백인 경우: 그냥 추가하되 isFirst를 true로
if c == " " {
result += String(c)
isFirst = true
continue
}
// 첫 글자인 경우
if isFirst {
// 문자인 경우: 대문자로 만들고 isFirst는 false로
if c.isLetter {
result += String(c.uppercased())
isFirst = false
// 문자가 아닌 경우 (= 숫자인 경우): 그냥 추가하고 isFirst는 false로
} else {
result += String(c)
isFirst = false
}
// 첫 글자가 아닌 경우: 문자만 나오므로 소문자로 바꾸어 추가
} else {
result += String(c.lowercased())
}
}
return result
}
String에서 String을 다루는 작업은 생각보다 무겁습니다. 이 작업 때문에 코드의 수행 시간이 10배가 차이나기도 합니다. Character를 String 타입으로 캐스팅하는 비용은 상대적으로 적게 든다고 하지만 String을 Array로 만들거나 Array를 합쳐서 String으로 만드는 작업 등은 상대적으로 무거운 작업에 속합니다. String을 Array로 만들면 각각의 Character에 subscript로 접근이 가능하는 등의 장점이 많지만 굳이 필요 없다면 사용하는 것을 지양합시다.
Character 타입에 있는 property입니다. 해당 Character가 문자인지 숫자인지 Bool 값으로 리턴해줍니다.