编辑代码

import Foundation  
  
// 定义一个函数,用于计算表达式的值  
func evaluate(_ expression: String) throws -> Double {  
    enum EvaluationError: Error {  
        case unbalancedParentheses  
        case invalidToken(String)  
        case divisionByZero  
    }  
  
    // 去除空格并将字符串分解为标记  
    let separator = CharacterSet.whitespaces.union(.newlines)  
    let tokens = expression.components(separatedBy: separator).filter { !$0.isEmpty } 
    //将输入的字符串按照空格和换行符进行分割,得到一个包含数字和运算符的数组。

    var values = [Double]()  // 数值栈  
    var ops = [Character]()  // 运算符栈  
      
    // 运算符优先级  
    let precedence: [Character: Int] = ["+": 1, "-": 1, "*": 2, "/": 2 , "^": 3]  
      
    // 应用运算符函数  
    func applyOp(_ op: Character, rhs: Double, lhs: Double) throws  -> Double {  
        switch op {  
        case "+": return lhs + rhs  
        case "-": return lhs - rhs  
        case "*": return lhs * rhs  
        case "/":  
            guard rhs != 0 else { throw EvaluationError.divisionByZero }  
            return lhs / rhs  
        case "^": return pows(lhs, rhs) // 使用pows函数进行乘方运算      
        default: fatalError("Unsupported operation")  
        }  
    }  
    func pows(_ base: Double, _ exponent: Double) -> Double {  
        let intPart = Int(exponent)  
 
        
        var result = 1.0  
        for _ in 0..<intPart {  
            result *= base  
        }    
        return result  
    }
    // 检查运算符的优先级  
    func hasPrecedence(op1: Character, over op2: Character) -> Bool {  
        guard let prec1 = precedence[op1], let prec2 = precedence[op2] else { return false }  
        return prec1 >= prec2  
    }  
      
//遍历分割后的数组,根据元素类型(数字或运算符)进行相应的处理。
// 如果遇到左括号,将其压入运算符栈;
//如果遇到右括号,从运算符栈中弹出运算符,并从数值栈中弹出两个数值进行计算
// 将结果压回数值栈,直到遇到左括号为止。
// 如果遇到其他运算符,根据优先级进行计算,并将结果压回数值栈。
// 最后,检查数值栈中是否只剩下一个数值,如果是,则返回该数值作为表达式的结果;否则,抛出异常  
    for token in tokens {
        if let value = Double(token) {  
            values.append(value)  
        } else if token == "(" {  
            ops.append("(")  
        } else if token == ")" {  
            while !ops.isEmpty && ops.last != "(" {  
                let op = ops.removeLast()  
                let rhs = values.removeLast()  
                let lhs = values.removeLast()
                do{
                    values.append(try applyOp(op, rhs: rhs, lhs: lhs))
                }  catch{
                    print("error:\(error)")
                }
                //values.append(try! applyOp(op, rhs: rhs, lhs: lhs))  
            }  
            if !ops.isEmpty && ops.last == "(" {  
                ops.removeLast()  
            } else {  
                throw EvaluationError.unbalancedParentheses  
            }  
        } else if let firstChar = token.first, precedence[firstChar] != nil {  
            // 运算符  
            while !ops.isEmpty && ops.last != "(" && hasPrecedence(op1:ops.last!, over: firstChar) {  
                let op = ops.removeLast()  
                let rhs = values.removeLast()  
                let lhs = values.removeLast()  
                do{
                    values.append(try applyOp(op, rhs: rhs, lhs: lhs))
                }  catch{
                    print("error:\(error)")
                }  
            }  
            ops.append(firstChar)  
        } else {  
            throw EvaluationError.invalidToken(token)  
        }  
    }  
      
    // 处理剩余的运算符  
    while !ops.isEmpty {  
        if ops.last == "(" {  
            throw EvaluationError.unbalancedParentheses  
        }  
        let op = ops.removeLast()  
        let rhs = values.removeLast()  
        let lhs = values.removeLast()  
        do{
            values.append(try applyOp(op, rhs: rhs, lhs: lhs))
        }catch{
           print("error:\(error)") 
        }
        
    }  
      
    guard values.count == 1 else { throw EvaluationError.unbalancedParentheses }  
    return values.first!  
}  
  
repeat {  
    print("请选择操作:1 - 计算, 0 - 退出")  
    if let operation = readLine(), let op = Int(operation) {  
        switch op {  
        case 1:  
            print("请输入一个数学表达式:")  
            if let input = readLine()?.trimmingCharacters(in: .whitespacesAndNewlines) {  
                do {  
                    let result = try evaluate(input)  
                    print("\(input) = \(result)")  
                } catch {  
                    print("表达式求值错误:\(error)")  
                }  
            } else {  
                print("未输入有效的表达式。")  
            }  
  
        case 0:  
            exit(EXIT_SUCCESS) // 输入0时退出程序  
        default:  
            print("无效的操作。")  
        }  
    } else {  
        print("未输入有效的操作。")  
    }  
} while true // 这里使用了 true 作为条件,表示无限循环,直到在循环体内退出