编辑代码

import Foundation

// 定义运算符优先级
let operatorPrecedence: [Character: Int] = ["+": 1, "-": 1, "*": 2, "/": 2, "^": 3, "v": 3]

class Calculator {
    // 计算表达式的入口函数
    func run() {
        print("请输入数学表达式:")

        // 从控制台读取输入的数学表达式
        if let input = readLine() {
            do {
                // 计算并输出结果
                let result = try calculate(input)
                print("计算结果: \(result)")
            } catch {
                print("错误: \(error)")
            }
        } else {
            print("输入无效。")
        }
    }

    // 计算表达式的主函数,可能抛出错误
    func calculate(_ expression: String) throws -> Double {
        let tokens = try tokenize(expression)
        let postfixTokens = infixToPostfix(tokens)
        let result = try evaluatePostfix(postfixTokens)
        return result
    }

    // 将表达式分解成词法单元,可能抛出错误
    private func tokenize(_ expression: String) throws -> [String] {
        var tokens: [String] = []
        var currentToken = ""

        for char in expression {
            if char.isNumber || char == "." {
                currentToken.append(char)
            } else {
                if !currentToken.isEmpty {
                    tokens.append(currentToken)
                    currentToken = ""
                }
                if char != " " {
                    tokens.append(String(char))
                }
            }
        }

        if !currentToken.isEmpty {
            tokens.append(currentToken)
        }

        return tokens
    }

    // 将中缀表达式转换为后缀表达式
    private func infixToPostfix(_ infixTokens: [String]) -> [String] 
    {
        var output: [String] = []
        var stack: [String] = []

        for token in infixTokens {
            if let number = Double(token) {
                output.append(String(number))
            } else if token == "(" {
                stack.append(token)
            } else if token == ")" {
                while let top = stack.last, top != "(" {
                    output.append(stack.removeLast())
                }
                stack.removeLast()
            } else {
                while let top = stack.last,
        let precedence1 = operatorPrecedence[token.first!],
        let precedence2 = operatorPrecedence[top.first!],
        precedence1 <= precedence2 {
                    output.append(stack.removeLast())
                }
                stack.append(token)
            }
        }

        while !stack.isEmpty {
            output.append(stack.removeLast())
        }

        return output
    }

    // 计算后缀表达式,可能抛出错误
    private func evaluatePostfix(_ postfixTokens: [String]) throws -> Double {
        var stack: [Double] = []

        for token in postfixTokens {
            if let number = Double(token) {
                stack.append(number)
            } else {
                let operand2 = stack.removeLast()
                let operand1 = stack.removeLast()

                switch token {
                case "+": stack.append(operand1 + operand2)
                case "-": stack.append(operand1 - operand2)
                case "*": stack.append(operand1 * operand2)
                case "/":
                    guard operand2 != 0 else {
                        throw CalculatorError.divisionByZero
                    }
                    stack.append(operand1 / operand2)
                case "^": stack.append(pow(operand1, operand2))
                case "v": stack.append(pow(operand1, 1/operand2))
                default:
                    throw CalculatorError.invalidOperator
                }
            }
        }

        return stack.first ?? 0.0
    }
}

// 定义计算器错误类型
enum CalculatorError: Error {
    case invalidOperator
    case divisionByZero
}

// 示例用法
let calculator = Calculator()
calculator.run()