1️⃣ 문제
2️⃣ 풀이 방법 및 코드
사실 문제에서 시키는대로, 아래와 같이 재귀 코드를 작성하면 되는 구현 문제였다.
1. 입력이 빈 문자열인 경우, 빈 문자열을 반환합니다.
2. 문자열 w를 두 "균형잡힌 괄호 문자열" u, v로 분리합니다. 단, u는 "균형잡힌 괄호 문자열"로 더 이상 분리할 수 없어야 하며, v는 빈 문자열이 될 수 있습니다.
3. 문자열 u가 "올바른 괄호 문자열" 이라면 문자열 v에 대해 1단계부터 다시 수행합니다.
3-1. 수행한 결과 문자열을 u에 이어 붙인 후 반환합니다.
4. 문자열 u가 "올바른 괄호 문자열"이 아니라면 아래 과정을 수행합니다.
4-1. 빈 문자열에 첫 번째 문자로 '('를 붙입니다.
4-2. 문자열 v에 대해 1단계부터 재귀적으로 수행한 결과 문자열을 이어 붙입니다.
4-3. ')'를 다시 붙입니다.
4-4. u의 첫 번째와 마지막 문자를 제거하고, 나머지 문자열의 괄호 방향을 뒤집어서 뒤에 붙입니다.
4-5. 생성된 문자열을 반환합니다.
다만 풀면서 고민했던 점으로 올바른 괄호 문자열을 확인하는 방법이었다.
처음에는 스택으로 문자열을 다 검사했었는데,
균형잡힌 문자열이 들어온다는 조건 때문에 u의 첫번째 원소가 “(“ 이기만 하면 무조건 u가 올바른 문자열임을 알 수 있다는 점을 깨달았다.
String을 extension 하여 확인할 수 있는 Bool 프로퍼티를 이용하였다.(isRigthP)
소스 코드
extension String {
// 올바른 괄호 문자열인지 확인하는 Bool
var isRightP: Bool {
return self.first! == "(" ? true: false
}
}
// 올바른 괄호 문자열로 수정
func edit(_ u: String, _ v: String) -> String {
var w = "(\(v))"
u.enumerated().forEach {
if $0.0 != 0 && $0.0 != u.count - 1 {
w += $0.1 == ")" ? "(": ")"
}
}
return w
}
func implement(_ p: String) -> String {
// 입력이 빈 문자열인 경우, 빈 문자열을 반환
guard !p.isEmpty else { return "" }
// 문자열 w를 두 "균형잡힌 괄호 문자열" u, v로 분리
var pCopy = p
var left = 0, right = 0
var u = "", v = ""
repeat {
switch pCopy.first! {
case "(":
left += 1
default:
right += 1
}
u.append(pCopy.removeFirst())
} while !pCopy.isEmpty && left != right
v = pCopy
// 문자열 u가 "올바른 괄호 문자열" 이라면 문자열 v에 대해 1단계부터 다시 수행
// 수행한 결과 문자열을 u에 이어 붙인 후 반환
return u.isRightP ? u + (v): edit(u, implement(v))
}
func solution(_ p:String) -> String {
return implement(p)
}
3️⃣ 이 문제를 풀면서 되새긴 점
repeat-while 구문
늘 while문만 써오다보니, repeat-while 구문 존재를 까먹고 있었다. 이번 문제처럼 처음에는 조건 검사없이 구문을 반복해야 할 때 유용하게 사용하도록 하자!
repeat {
/*실행 구문*/
} while 조건