Stanford CS193p iOS开发课程笔记(二)

今天进行了CS193P第三课的学习,课程的主要目标是通过MVC的模式来完成计算器DEMO.但是DEMO的计算方法是通过模拟入栈出栈以及通过递归的方式来进行.我对栈以及递归还不是很熟悉.所以学习效果很差,只弄懂了前50分中左右的内容.
第一遍照着代码完全的敲了下来,没有遇到swift版本转换的问题.主要还是要细心.
第二遍看还是没能完全明白递归的部分,待学习递归后还是要进行第三遍的学习.

具体代码如下,目前将学到的地方都进行了注释

  • Model部分
import Foundation //iOS的核心服务层,永远不要再model里导入UIKit

class CalculatorBrain {
    private enum Op { //利用枚举的计算属性
        case Operand(Double)  //操作数
        case UnaryOperation(String, Double -> Double)  //一元运算,String表示符号,在这里实际表示"√"
        case BinaryOperation(String, (Double, Double) -> Double)  //二元运算,这里String是加减乘除
        
        var description:String {
            get {
                switch self {
                case .Operand(let operand):
                    return "\(operand)"
                case .UnaryOperation(let symbol,_ ):
                    return symbol
                case .BinaryOperation(let symbol, _):
                    return symbol
                }
            }
        }

    }

    private var opStack = [Op]()  //运算栈
    
    private var knownOps = [String:Op]() //创建字典,key是string也就是操作符,Op是value也就是操作数
    
    init() {
        func learnOp(op:Op) {
            knownOps[op.description] = op
        }
        learnOp(Op.BinaryOperation("×", *))
        learnOp(Op.BinaryOperation("÷", {$1 / $0}))
        learnOp(Op.BinaryOperation("+", +))
        learnOp(Op.BinaryOperation("−", {$0 - $1}))
        learnOp(Op.UnaryOperation("√", sqrt))
    }
    
    private 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)//此处就意味着返回最后一个操作数result和剩下的操作符
            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(op1Evaluation.remainingOps)
                    if let operand2 = op2Evaluation.result {
                        return (operation(operand1, operand2), op2Evaluation.remainingOps)
                }
                    
               }
                
            }
        }
        return (nil,ops)
    }
    
    func evaluate() -> Double? {
        let (result, remainder) = evaluate(opStack)

        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()
    }
}

  • Controller部分
import UIKit

class ViewController: UIViewController {


    @IBOutlet weak var display: UILabel!
    
    var userIsInTheMiddleOfTypingANumber = false  //用来判断是否已经输入了数字,初始默认为未输入
    
    var brain = CalculatorBrain() //用来连接Controller和Model

    @IBAction func appendDigit(sender: UIButton) {//此处实现了,让所有数字button都集中在这一个方法里
        let digit = sender.currentTitle! //此处用来识别是按了哪个数字,digit的类型为String
        print("digit = \(digit)")
        //此处判断是否正在输入数字
        if userIsInTheMiddleOfTypingANumber {
            display.text = display.text! + digit
        } else {
            display.text = digit
            userIsInTheMiddleOfTypingANumber = true
        }

    }


    @IBAction func operate(sender: UIButton) { //创建运算符操作方法
        if userIsInTheMiddleOfTypingANumber {
            enter()
        }
        if let operation = sender.currentTitle {
            if let result = brain.performOperation(operation){
                displayValue = result
            }else {
                displayValue = 0
            }
        }
        
    }
    
    @IBAction func enter() {
        userIsInTheMiddleOfTypingANumber = false
        if let result = brain.pushOperand(displayValue) {
            displayValue = result
        }else {
            displayValue = 0
        }
    }

    
    var displayValue: Double {
        get {
            return NSNumberFormatter().numberFromString(display.text!)!.doubleValue //将display.text转化为Double类型
        }
        set {
            display.text = "\(newValue)"    //此处的newValue为默认名称.因为没有给setter定义新的参数名.若设置则可set(新参数名){}

        }
    }
}


你可能感兴趣的:(Stanford CS193p iOS开发课程笔记(二))