1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
| // // CalculatorBrain.swift // Calculator // // Created by Will Ge on 7/11/15. // Copyright © 2015 gewill.org. All rights reserved. //
import Foundation
class CauculatorBrain { // 定义一个枚举类型,来分类表示输入的:运算数、一元运算和二元运算 enum Op { case Operand(Double) case UnaryOperation(String, Double -> Double) case BinaryOperation(String, (Double, Double) -> Double) } // 定义一个数组来储存所有输入 var opStack = [Op]() // 定义已知运算符 var knownOps = [String:Op]() // 初始化已知运算符 init() { knownOps["+"] = Op.BinaryOperation("+", +) knownOps["−"] = Op.BinaryOperation("−") {$1 - $0} knownOps["×"] = Op.BinaryOperation("×", *) knownOps["÷"] = Op.BinaryOperation("÷") {$1 / $0} knownOps["√"] = Op.UnaryOperation("√", sqrt) } // 定义一个函数,把输入递归取出 func evaluate(ops: [Op]) -> (result: Double?, remainingOps:[Op]) { if !ops.isEmpty { var remainingOps = ops let op = remainingOps.removeLast() switch op { case.Operand(let operand): return (operand, remainingOps) case .UnaryOperation(_, let operation): let operandEvaluation = evaluate(remainingOps) if let operand = operandEvaluation.result { return (operation(operand), operandEvaluation.remainingOps) } case .BinaryOperation(_, let operation): let op1Evaluation = evaluate(remainingOps) if let operand1 = op1Evaluation.result { let op2Evaluation = evaluate(remainingOps) if let operand2 = op2Evaluation.result { return (operation(operand1, operand2), op2Evaluation.remainingOps) }
} } } return (nil, ops) } func evaluate() -> Double? { let (result, remainder) = evaluate(opStack) print("\(opStack) = \(result) with \(remainder) left over") return result } // 运算数 func pushOperand(operand: Double) -> Double? { opStack.append(Op.Operand(operand)) return evaluate() } // 运算符 func performOperation(symbol: String) -> Double? { if let operation = knownOps[symbol] { opStack.append(operation) } return evaluate() } }
|