编辑代码

import Foundation

class EnhancedCalculator {
    // 计算表达式的主函数
    func calculate(_ expression: String) -> Double {
        let tokens = tokenize(expression)
        let rpn = infixToPostfix(tokens)
        return evaluateRPN(rpn)
    }
    
    // 将输入的数学表达式转换为单独的标记(token)
    private func tokenize(_ expression: String) -> [String] {
        var tokens = [String]()
        var number = ""
        for char in expression {
            if char.isWhitespace {
                continue
            } else if char.isNumber || char == "." {
                number.append(char)
            } else {
                if !number.isEmpty {
                    tokens.append(number)
                    number = ""
                }
                tokens.append(String(char))
            }
        }
        if !number.isEmpty {
            tokens.append(number)
        }
        return tokens
    }
    
    // 将中缀表达式转换为后缀表达式
    private func infixToPostfix(_ tokens: [String]) -> [String] {
        var output = [String]()
        var operators = [String]()
        let precedence: [String: Int] = [
            "+": 1, "-": 1,
            "*": 2, "/": 2,
            "^": 3, "√": 3,
            "(": 0, ")": 0
        ]
        
        for token in tokens {
            if let _ = Double(token) {
                output.append(token)
            } else if token == "(" {
                operators.append(token)
            } else if token == ")" {
                while let top = operators.last, top != "(" {
                    output.append(operators.removeLast())
                }
                operators.removeLast()
            } else {
                while let top = operators.last, precedence[top]! >= precedence[token]! {
                    output.append(operators.removeLast())
                }
                operators.append(token)
            }
        }
        
        while operators.last != nil {
            output.append(operators.removeLast())
        }
        
        return output
    }
    
    // 计算逆波兰表示法表达式的结果
    private func evaluateRPN(_ tokens: [String]) -> Double {
        var stack = [Double]()
        for token in tokens {
            if let value = Double(token) {
                stack.append(value)
            } else if token == "√" {
                if let operand = stack.popLast() {
                    stack.append(sqrt(operand))
                }
            } else if let right = stack.popLast(), let left = stack.popLast() {
                switch token {
                case "+":
                    stack.append(left + right)
                case "-":
                    stack.append(left - right)
                case "*":
                    stack.append(left * right)
                case "/":
                    stack.append(left / right)
                case "^":
                    stack.append(pow(left, right))
                default:
                    fatalError("Unexpected operator: \(token)")
                }
            }
        }
        return stack.last ?? 0.0
    }
}

let calc = EnhancedCalculator()

// 测试二级运算符识别及括号优先级
let expr1 = "3+5*4"
let expr2 = "1+(3+5)*4"

let result1 = calc.calculate(expr1)
print("\(expr1) = \(result1)") // 应输出 23

let result2 = calc.calculate(expr2)
print("\(expr2) = \(result2)") // 应输出 33