괄호의 짝을 맞추는 문제로 전형적인 stack을 활용해서 풀어야 하는 문제입니다. 하지만 이 문제의 복잡한 점은 stack에 괄호만 들어가는 것이 아니라 괄호의 값을 넣어서 계산해주어야 한다는 것인데요. 여는 괄호를 push하고 닫는 괄호일 때 pop해서 짝을 맞추어보는 것은 동일하지만 중간에 짝을 이룰 때마다 계산해서 stack에 푸시합니다.
말로면 설명하니 쉽지 않네요. (()[[]])
의 괄호의 값을 계산해보면서 설명을 해보겠습니다.
import Foundation
// 입력 받기
let string = readLine()!.map { String($0) }
var stack = [String]()
// 올바르지 않은 문자열인 경우 0 출력하고 프로그램 종료
func exitWithPrintingZero() {
print(0)
exit(0)
}
// 괄호들을 순회하면서
for s in string {
//1. 여는 괄호의 경우 stack에 push
if s == "(" || s == "[" {
stack.append(s)
//2. 닫는 소괄호의 경우
} else if s == ")" {
var temp = 0 // 계산 결과를 담아놓는 임시 변수
guard !stack.isEmpty else { exitWithPrintingZero(); break }
//👉 만약에 stack이 비었다면 여는 괄호와 짝을 이룰 수 없으므로 종료
while !stack.isEmpty {
let popped = stack.popLast()!
//2-1. 여는 괄호를 만나면 지금까지의 계산 결과에 2를 곱해서 (단 0인 경우 2) push하고 break (짝을 찾음)
if popped == "(" {
stack.append(temp == 0 ? "2" : "\(2 * temp)")
break
//2-2. 짝이 맞지 않는 여는 괄호를 만나면 잘못된 짝이므로 종료
} else if popped == "[" {
exitWithPrintingZero()
//2-3. 숫자를 만나면 덧셈 계산
} else {
temp += Int(popped)!
}
}
//3. 닫는 대괄호의 경우
} else if s == "]" {
var temp = 0
guard !stack.isEmpty else { exitWithPrintingZero(); break }
while !stack.isEmpty {
//3-1. 여는 괄호를 만나면 지금까지의 계산 결과에 3를 곱해서 (단 0인 경우 3) push하고 break (짝을 찾음)
let popped = stack.popLast()!
if popped == "[" {
stack.append(temp == 0 ? "3" : "\(3 * temp)")
break
//3-2. 짝이 맞지 않는 여는 괄호를 만나면 잘못된 짝이므로 종료
} else if popped == "(" {
exitWithPrintingZero()
//3-3. 숫자를 만나면 덧셈 계산
} else {
temp += Int(popped)!
}
}
}
}
var ans = 0
// stack에 남은 숫자 더해서 답 구하기
for str in stack {
guard let num = Int(str) else { exitWithPrintingZero(); break }
ans += num
}
print(ans)