특별히 해당 문제는 입출력 예 화면을 올렸습니다. 카카오는 역시 카카오라는 생각이 든 것은 풀이방법을 제시해 줌에도 불구하고 어려운 문제를 만들어냈다는 것에 다시 한번 감탄한 문제입니다.
이 문제는 개인적으로 생각해보았을 때 '재귀함수를 응용할 수 있는가' 라는 질문에 대한 대답인 것 같습니다. 실제 웹 프로그래밍이나 앱 프로그래밍에서는 많이 써보지 않아서 이해하는 것이 힘들었지만 이번 기회에 한번 써볼 수 있어서 좋았습니다.
이 문제에는 두 개의 키워드가 있습니다.
균형잡힌 괄호 문자열 => "(", ")" 의 갯수가 같은 문자열.
(예. "(())", "))((", ")((())", "()")
올바른 괄호 문자열 => "(", ")" 의 갯수와 짝이 맞는 문자열.
(예. "()", "(())", "()(())", "(()())")
'매개변수 설명' 에 보면 유추해 볼 수 있는 정보는 p 파라미터는 균형잡힌 괄호 문자열이며, 짝수(2이상)입니다. 이를 통해 구현해야 할 guard문을 구현할 필요는 없었습니다.
import Foundation
func solution(_ p:String) -> String {
var p = p
return splitRepeatedly(vValue: &p)
}
//균형잡힌 괄호 문자열 반환
func splitBracket(_ str: String) -> [String: String] {
var str = str
var uTemp = String(str.removeFirst())
while uTemp.filter({$0=="("}).count != uTemp.filter({$0==")"}).count {
uTemp += String(str.removeFirst())
}
return ["u":uTemp,"v":str]
}
//올바른 괄호 문자열인지
func isRightBracket(_ str: String) -> Bool {
guard str.first == "(" && str.count != 0 && str.count.isMultiple(of: 2) else {
return false
}
var str = str
while !str.isEmpty {
let middlePoint = str.firstIndex(of: str.first! == ")" ? "(" : ")")!
let lhs = String(str[str.index(before: middlePoint)])
let rhs = String(str[middlePoint])
if lhs != rhs {
str = String(str[..<str.index(before: middlePoint)]+str[str.index(after: middlePoint)...])
} else {
break
}
}
return str.isEmpty
}
func splitRepeatedly(vValue: inout String) -> String {
let splited = splitBracket(vValue)
if var uValue = splited["u"], var vValue = splited["v"] {
let temp = vValue == "" ? vValue : splitRepeatedly(vValue: &vValue) //재귀함수를 호출하는 부분. v로 호출할 수 없을 때까지 수행.
if isRightBracket(uValue) { //올바른 괄호 문자열이라면
return uValue + temp
} else { //올바른 괄호 문자열이 아니라면
uValue.removeFirst()
uValue.removeLast()
return "("+temp+")"+uValue.map{$0 == "(" ? ")" : "("}.reduce(""){$0+$1}
}
}
return vValue
}
제가 풀때는 10시쯤 시작하여 새벽1시까지 못풀었는데, 4-2 의 설명을 잘 읽지 않아서 재귀함수를 호출하는 조건을 제대로 파악하지 못했습니다.
한번 풀어보시길 바랍니다.