美文网首页
Swift花边知识点

Swift花边知识点

作者: T92 | 来源:发表于2016-08-20 15:01 被阅读236次

    大概内容

    递归,异常,索引,断言

    递归

    //求C(m,n)函数m!/n!/(m-n)! = m!/(n!*(m-n)!)或者n*(n-1)!
    func Cmn(m:Int, _ n:Int) ->Int{
        assert(m >= n,"m必须大于等于n")//断言,m小于n时提示用户"m必须大于等于n"
        return  Int(a3(m) / a3(n) / a3(m - n))
    }
    /*
    //n*(n-1)! 采用递归方法,效率没有采用循环的效率高
    func f(n:Int) -> Double{
        if n == 0 || n == 1{
            return 1
        } //收敛
        return Double(n) * f(n - 1)//条件
    }
    
    //函数递归调用(一个函数直接或者间接的调用自身),采用递归方法,效率没有采用循环的效率高,能用循环写出的就用循环,很麻烦很复杂的问题可以采用递归
    //使用递归必须要有
    //1.递归公式
    //2.收敛条件
    */
    
    //用递归计算1-n的和
    func sum(n:Int) -> Int{
        if n == 1{
            return 1
        }
        return n + sum(n - 1)
    }
    

    异常

    Fraction 分数类

    //x和y的最大公约数跟y%x的最大公约数是一样的(欧几里得算法)
    //求最大公约数
    func gcd(x:Int, _ y:Int) ->Int{
        if x > y{
            return gcd(y, x)
        }
        else if y % x != 0{
            return gcd(y % x, x)
        }
        else {
            return x
        }
    }
    
    //定义一个遵循ErrorType协议的枚举
    //通过不同的case定义程序中可能出现的若干异常状况
    
    /**
    - ZeroDenominator:分母为0
    - DividByZero:除数为0
    */
    enum FractionError:ErrorType{
        case ZeroDenominator,DividByZero
    }
    
    class Fraction{
        private var _num:Int //分子
        private var _den:Int //分母
        
        
    //   如果一个方法抛出了异常,那么在声明方法时必须写上throws关键字
        init(num:Int,den:Int) throws {
            _num = num
            _den = den
    //        如果程序中出现问题就抛出异常
    //        被throw关键字抛出的必须遵循ErrorType协议
            if _den == 0{
                throw FractionError.ZeroDenominator
            }
            else{
                normoalize()
                simplify()
            }
        }
    
        var info:String{
            get {
                return _num == 0 || _den == 1 ? "\(_num)" : "\(_num)/\(_den)"
            }
        }
        
        
        func add(other:Fraction) throws -> Fraction{
            return try Fraction(num: _num * other._den + other._num * _den, den: _den * other._den)
           
            
        }
        
        func sub(other:Fraction) throws ->Fraction{
            return try Fraction(num: _num * other._den - other._num * _den, den: _den * other._den)
            
            
        }
    
        func mul(other:Fraction) throws ->Fraction{
            return try Fraction(num: _num * other._num, den: _den * other._den)
        }
        
        func div(other:Fraction) throws ->Fraction{
            if other._num == 0{
                throw FractionError.DividByZero
            }
            return try! Fraction(num: _num * other._den, den: _den * other._num)
        }
        
        func normoalize() ->Fraction{
            if _den < 0{
                _num = -_num
                _den = -_den
            }
            return self
        }
        
        func simplify() ->Fraction{
            if _num == 0{
                _den = 1
            }
            else{
                let x = abs(_num)
                let y = abs(_den)
                let g = gcd(x, y)
                _num /= g
                _den /= g
            }
            return self //返回本身的分数对象
        }
        
    }
    
    //运算符重载 (为自定义的类型定义运算符)
    func +(one:Fraction,two:Fraction) -> Fraction{
    //    如果能够保证方法调用时不出现异常那么可以在try后面加!
    //    这样就可以在不写do...catch的情况下调用可能出状况的方法
        return try! one.add(two)
    }
    
    func -(one:Fraction,two:Fraction) -> Fraction{
        return try! one.sub(two)
    }
    
    func *(one:Fraction,two:Fraction) -> Fraction{
        return try! one.mul(two)
    }
    
    func /(one:Fraction,two:Fraction) throws -> Fraction{
        return try one.div(two)
    }
    

    测试

    //对于可能出状况的代码要放到do...catch语句中
    //在可能出状况的代码前面还要加上try,表示尝试执行
    //如果在do中的代码没有出任何状况那么catch就不会执行
    //如果do中出现状况,代码就不会继续往下执行,而是转移到catch中
    //在do的后面可以跟上多个catch用于捕获不同的状况,但是最多只有一个catch会被执行
    do {
        let f1 = try Fraction(num: 3, den: 0)
        let f2 = try Fraction(num: 0, den: 5)
        
        let f3 = f1 + f2
        print(f3.info)
        let f4 = f1 - f2
        print(f4.info)
        let f5 = f1 * f2
        print(f5.info)
        let f6 = try f1 / f2
        print(f6.info)
    }
    catch FractionError.ZeroDenominator{
        print("分母不能为0")
    }
    catch FractionError.DividByZero{
        print("除数不能为0")
    }
    catch{
        print("出错了,我也不知道什么问题")
    }
    
    //不想写do...catch时也可以写成下面的代码
    func foo(){
    //    如果能保证代码不出错可以在try后面加!
    //    如果不能保证代码是否会出错可以在代码后面加?
    //    需要注意的是由?的地方会产生optional
    //    稍后可能还需要对可空类型进行拆封且方式有二:
    //    1.不安全的做法:xxx!
    //    2.安全的做法:有if let = xxx
        let f1 = try? Fraction(num: 3, den: 0)
        let f2 = try? Fraction(num: 0, den: 5)
        
    //    let c = f1! + f2!  //不安全
        
    //    安全
        if let a = f1, b = f2{
            let c = a + b
            print(c.info)
        }
        else{
            print("无效的分数不能运算")
        }
    }
    

    索引

    例子1

    片段代码,详细参考gobangApp改进版

    //建立索引****
        subscript(row:Int,col:Int) -> Bool{
            get{ return board[row][col] == .Space }
            set(isBlack){
                if board[row][col] == .Space{
                    board[row][col] = isBlack ? .Black : .White
                    isBlackTurn = !isBlackTurn
                }
            }
        }
    

    测试

    if board[row,col]{
                    board[row,col] = board.isBlackTurn
                    setNeedsDisplay()
    }
    

    例子2:生成随机验证码

    func randomNum(min:Int,_ max:Int) -> Int{
       return Int(arc4random_uniform(UInt32(max - min)) + 1) + min
    }
    
    //扩展原生API
    extension String{
        var lenth: UInt32 {
            get{ return UInt32(self.characters.count) }
        }
        //建立索引
        subscript(index:Int) -> Character{
            get { return self[self.startIndex.advancedBy(index)] }
        }
    }
    
    func generate(lenth:Int) ->String{
        var code = ""
        if lenth > 0{
            let str = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
            for _ in 0..<lenth - 1{
            code.append(str[randomNum(0, str.characters.count)])
            }
        }
        return code
    }
    print(generate(5))
    

    断言

    当需要判断是否满足某个条件时可以使用断言assert,满足条件程序继续执行,不满足就提示逗号后面的内容。

    let age = -3
    assert(age >= 0, "A person's age cannot be less than zero")
    // this causes the assertion to trigger, because age is not >= 0
    

    相关文章

      网友评论

          本文标题:Swift花边知识点

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