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)
number = ""
}
if char == "!" {
tokens.append("√")
} else {
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
}
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"))")
print("功能二:结果是:1+(3+5)*4= \(calc.calculate("1+(3+5)*4"))")
print("功能三:")
print("结果是: 2 + 3=\(calc.calculate("2 + 3"))")
print("结果是: 10 - 5=\(calc.calculate("10 - 5"))")
print("结果是: 4 * 6=\(calc.calculate("4 * 6"))")
print("结果是: 12 / 3=\(calc.calculate("12 / 3"))")
print("结果是: 2 ^ 3=\(calc.calculate("2 ^ 3"))")
print("结果是: \(calc.calculate("sin(30)"))")