import Foundation
func solution(_ expression:String) -> Int64 {
var args: [(Operator?, Int)] = [] // (연산자, 숫자) 담을 배열
// (연산자, 숫자) 튜플 형식으로 변환
let scanner = Scanner(string: expression)
let opertorStr = CharacterSet(charactersIn: "-+*")
let numStr = scanner.scanUpToCharacters(from: opertorStr)!
args.append((nil, Int(numStr)!))
while !scanner.isAtEnd {
if let operatorStr = scanner.scanCharacter() {
let oper = Operator(rawValue: "\(operatorStr)")
let numStr = scanner.scanUpToCharacters(from: opertorStr)!
args.append((oper, Int(numStr)!))
}
}
// 연산자 우선순위의 모든 경우의 수
var priorityOperators: [[Operator]] = []
Operator.priorityOperators(&priorityOperators)
// 최대값 구하기
var maxVal = 0
for priorityOperator in priorityOperators {
maxVal = max(operate(priorityOperator, args), maxVal)
}
return Int64(maxVal)
}
enum Operator: String, CaseIterable {
case plus = "+"
case minus = "-"
case multiple = "*"
// 연산자 우선순위의 모든 경우의 수 구하기
static func priorityOperators(_ arr: inout [[Operator]],
_ remains: [Operator] = Operator.allCases,
_ current: [Operator] = []) {
if remains.count == 0 {
arr.append(current)
return
}
for (index, oper) in remains.enumerated() {
var operators = current
var newRemains = remains
operators.append(oper)
newRemains.remove(at: index)
priorityOperators(&arr, newRemains, operators)
}
}
func caculate(_ arg1: Int, _ arg2: Int) -> Int {
switch self {
case .plus:
return arg1 + arg2
case .minus:
return arg1 - arg2
case .multiple:
return arg1 * arg2
}
}
}
// 우선순위에 맞게 계산해서 결과를 리턴한다.
func operate(_ priority: [Operator], _ args: [(Operator?, Int)]) -> Int {
var caculated = args
for oper in priority {
var isLoop = true
while isLoop {
isLoop = false
for (index, arg) in caculated.enumerated() {
if arg.0 == oper {
let result = oper.caculate(caculated[index - 1].1, arg.1)
caculated[index - 1].1 = result
caculated.remove(at: index)
isLoop = true
break
}
}
}
}
return abs(caculated[0].1)
}
사칙연산하지말고 연산자 우선순위 배치해서 제일 최대값 나오는 경우를 찾아내는 문제.
문자열 인자값 파싱하는 방법으로 Scanner를 이용해보았다.
지문도 단번에 이해가고 깔끔하고 괜찮았던 문제.