Swift 入門指南 V1.00 - 單元 17 - 修正後的數學公式




程式中可能會發生的錯誤有三種,分別是語法錯誤 (syntax error) 、執行期間錯誤 (run-time error) 及語意錯誤 (semantic error)



Xcode 會直接幫我們挑出語法錯誤,例如打錯識別字 (identifier) 或關鍵字 (keyword) 等。執行期間錯誤的話比較麻煩,大多數的情況由選擇型態 (optionals) 的機制防範,其他有些則要程式設計師自己寫相關控制機制,不過這些依經驗法則就知道有哪些,像是檔案處理或網路部分。三種錯誤中最麻煩的,就是語意錯誤了,因為有語意錯誤的程式,程式可以順利執行完畢,卻跑出錯誤的結果。


我們的 Encrypt 類別 (class) 目前正是碰到了發生語意錯誤的情況,這是說


y = a * x + b

m = y % n


其中 ab 若是 09 隨機整數,有些組合成立,可以得到正確結果,有些組合卻會得到錯誤的結果,這是為什麼呢?嗯,好麻煩唷!這樣就得討論好多數學,打斷我們發展程式的腳步,所以我們不打算仔細討論這背後的數學理論,我們繼續測試,直接來找出哪些 ab 組合會得到錯誤的結果吧!


要知道哪些組合可能會發生錯誤,我們就得知道 ab 的值,這不難,印出來就看得到了。我們先把 absetCode() 中的區域變數 (local variable) 調整為屬性 (property) , Encrypt 類別修改如下


class Encrypt {
   // 英文小寫字母表
   let alphabet = "abcdefghijklmnopqrstwuvxyz"
   // 密碼表整數陣列
   var code = Array(arrayLiteral: 26)
   // 把 a 、 b 暫時提升為屬性
   var a = 0
   var b = 0
 
   // 建構子
   init() {
      setCode()
   }
 
   // 設定密碼表
   func setCode() {
      a = Int(arc4random() % 10)
      b = Int(arc4random() % 10)
 
      var c = 97
      var i, x, y, m: Int
      // 以迴圈取得每一個餘數
      for i = 0; i < 26; i++ {
         x = c
         y = x * a + b
         m = y % 26
         code.append(m)
         c++
      }
 
      // 移除第一個預設值
      code.removeAtIndex(0)
   }
 
   // 以下註解化部份略去
}

測試部分加入印出 ab 值,在 Playground 的執行結果如下



結果顯示 a 為偶數或 0 就會跑出不符預期的結果,那我們就把 a 改成不是偶數或 0 好了!公式修改如下


if (a % 2) != 0 {

   y = a * x + b

   m = y % n

}


這樣 setCode() 在取得 ab 值的部分修改如下


// a 必須是奇數
while a % 2 == 0 {
   a = Int(arc4random() % 10)
   b = Int(arc4random() % 10)
}

測試部分重新執行,結果如下



肉眼檢查下,似乎只要 a 為奇數,計算出的結果就不會有問題囉!


下個單元我們要開始實作處理編碼的部分,也就是實作 toEncode() 方法 (method) 。


中英文術語對照


語法錯誤syntax error
執行期間錯誤run-time error
語意錯誤semantic error
識別字identifier
關鍵字keyword
選擇型態keyword
類別class
區域變數local variable
屬性property
方法method

沒有留言: