编辑代码

import Foundation

class SimplifiedCalculator {
    func calculate(_ expression: String) -> Double {
        
        if expression.contains("sin") {
            return evaluateExpressionWithSine(expression)
        } else {
            let tokens = tokenize(expression)
            let rpn = infixToPostfix(tokens)
            return evaluateRPN(rpn)
        }
    }

    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) // 将构建的数字加入 tokens
                    number = ""
                }
                if char == "!" { // 将 '!' 视为开根号
                    tokens.append("√")
                } else {
                    tokens.append(String(char)) // 处理其他操作符和括号
                }
            }
        }
        if !number.isEmpty {
            tokens.append(number) // 将最后一个数字加入 tokens
        }
        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
    }

    private func evaluateSin(_ degree: Double) -> Double {
        let radians = degree * Double.pi / 180.0
        var a = radians
        var b = 1.0
        var c = 1.0
        var sum = 0.0
        for i in 1...10 {
            let num = a / b * c
            b *= Double(2 * i) * Double(2 * i + 1)
            a *= radians * radians
            c = -c
            sum += num
        }
        return sum
    }

    func evaluateExpressionWithSine(_ expression: String) -> Double {
        var result: Double = 0.0
        var numberString = ""
        var inSineFunction = false

        for char in expression {
            if char == "s" {
                inSineFunction = true
            } else if char.isNumber || char == "." {
                numberString.append(char)
            } else {
                if !numberString.isEmpty {
                    if let value = Double(numberString) {
                        if inSineFunction {
                            result += evaluateSin(value)
                        } else {
                            result += value
                        }
                    } else {
                        return 0.0
                    }
                    numberString = ""
                }
                }
                if char == "s" {
                    inSineFunction = false
                }
            }
        

        // 处理字符串末尾可能遗留的数字
        if !numberString.isEmpty {
            if let value = Double(numberString) {
                if inSineFunction {
                    result += evaluateSin(value)
                } else {
                    result += value
                }
            } else {
                return 0.0
            }
        }

        return result
    }
}

let calc = SimplifiedCalculator()
print("功能一:结果是:3+5*4= \(calc.calculate("3+5*4"))") // 应输出23
print("功能二:结果是:1+(3+5)*4= \(calc.calculate("1+(3+5)*4"))") // 应输出33
print("功能三:") 
print("结果是: 2 + 3=\(calc.calculate("2 + 3"))") // 应输出5
print("结果是: 10 - 5=\(calc.calculate("10 - 5"))") // 应输出5
print("结果是: 4 * 6=\(calc.calculate("4 * 6"))") // 应输出24
print("结果是: 12 / 3=\(calc.calculate("12 / 3"))") // 应输出4.0
print("结果是: 2 ^ 3=\(calc.calculate("2 ^ 3"))") // 应输出8
print("结果是: \(calc.calculate("sin(30)"))") // 应输出sin(30°)的近似值