美文网首页
Stanford CS193p iOS开发课程笔记(二)

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

作者: Dominic1992 | 来源:发表于2015-12-03 00:12 被阅读183次

    今天进行了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开发课程笔记(二)

          本文链接:https://www.haomeiwen.com/subject/uqcshttx.html