编辑代码

import Foundation
// 定义运算符的优先级
let precedence: [Character: Int] = [
"+": 1,
"-": 1,
"*": 2,
"/": 2,
"^": 3,
"√": 3
]
// 定义运算符的结合性
let associativity: [Character: Bool] = [
"+": true,
"-": true,
"*": true,
"/": true,
"^": false,
"√": false
]
// 判断字符是否为运算符
func isOperator(_ char: Character) -> Bool {
return precedence.keys.contains(char)
}
// 判断字符是否为数字
func isNumber(_ char: Character) -> Bool {
return char.isNumber || char == "."
}
// 进行运算
func performOperation(_ operand1: Double, _ operatorChar: Character,
_ operand2: Double) -> Double {
switch operatorChar {
case "+":
return operand1 + operand2
case "-":
return operand1 - operand2
case "*":
return operand1 * operand2
case "/":
// 检查除数是否为零
        if operand2 == 0 {
            print("错误:除数不能为零!")
            return Double.nan
        }
return operand1 / operand2
case "^":
return pow(operand1, operand2)
case "√"://alt+41420 
return pow(operand2, 1/operand1)
default:
return 0
}
}

// 将字符串表达式转换为后缀表达式
func convertToRPN(_ expression: String) -> [String] {
 // 创建一个空的字符串数组output,用于存储转换为RPN的结果
var output: [String] = []
// 创建一个字符堆栈stack,用于临时存储运算符
var stack: [Character] = []
// 创建一个字符串numberBuffer,用于临时存储数字
var numberBuffer = ""
 // 遍历输入表达式中的每一个字符
for char in expression {
if isNumber(char) {
// 如果当前字符是数字,则将其添加到numberBuffer中
numberBuffer += String(char)
} else {
// 如果当前字符不是数字(即它是一个运算符),则执行以下操作:
if !numberBuffer.isEmpty {
// 如果numberBuffer不为空,则将这个数字添加到output数组中,并清空numberBuffer
output.append(numberBuffer)
numberBuffer = ""
}
if isOperator(char) {
while let top = stack.last, isOperator(top) &&
((associativity[char]! && precedence[char]! <= precedence[top]!)
|| (!associativity[char]! && precedence[char]! < precedence[top]!))
// 如果char是左结合的,且优先级小于或等于top的优先级,那么就将top弹出并添加到输出队列中。
//如果char是右结合的,且优先级小于top的优先级,那么就将top弹出并添加到输出队列中。
{
output.append(String(stack.removeLast()))
}
// 将当前运算符压入栈中
stack.append(char)
} else if char == "(" {
stack.append(char)
} else if char == ")" {
// 如果当前字符是右括号,将栈中的运算符弹出并添加到输出队列中,直到遇到左括号为止
while let top = stack.last, top != "(" {
output.append(String(stack.removeLast()))
}
stack.removeLast()
}
}
}
 // 如果numberBuffer不为空,将其添加到输出队列中
if !numberBuffer.isEmpty {
output.append(numberBuffer)
}
 // 将栈中剩余的运算符弹出并添加到输出队列中
while let top = stack.last {
output.append(String(stack.removeLast()))
}
return output
}

// 计算后缀表达式的结果
func calculateRPN(_ rpn: [String]) -> Double {
var stack: [Double] = []
for token in rpn {
// 如果当前元素是数字,则将其压入堆栈中
if let number = Double(token) {
stack.append(number)
} else if isOperator(token.first!) {
 // 如果当前元素是运算符,则从堆栈中弹出两个数字,
 //进行运算,然后将结果压入堆栈中
let operand2 = stack.removeLast()
let operand1 = stack.removeLast()
let result = performOperation(operand1, token.first!,
operand2)
stack.append(result)
}
}
// 返回堆栈中的第一个元素,即RPN表达式的计算结果
return stack.first!
}
// 从控制台获取输入表达式
print("请输入一个表达式:")
if let expression = readLine() {
let rpn = convertToRPN(expression)
let result = calculateRPN(rpn)
print("结果:\(result)")
}