程式設計師的數學筆記2--餘數

spearhead_cai發表於2019-01-04

上一節程式設計師的數學筆記1--進位制轉換是介紹了進位制,特別是十進位制和二進位制之間的轉換,移位操作和邏輯操作。

今天介紹的是餘數,看完本節筆記,你會發現生活中有很多東西都有餘數的影子。


餘數

餘數的特性

整數是沒有邊界的,它可能是正無窮,也可能是負無窮。

**但餘數卻總是在一個固定的範圍內。**假如除數是 m,那麼餘數的範圍就是 0~(m-1)。

生活中,餘數可以用來算星期,web 程式設計中可以用於分頁。

同餘定理

兩個整數 a 和 b,如果它們除以正整數 m 得到的餘數相等,我們就可以說 a 和 b 對於模 m 同餘。

同餘定理可以用來做分類,或者說是均分操作。因為可以將對同個正整數 m 相除得到的餘數相等的分在同一個類中。

雜湊函式

每個程式語言都有對應的雜湊函式,雜湊有時候也被翻譯為雜湊,**它是指將任意長度的輸入,通過雜湊演算法壓縮為某一固定長度的輸出。**這其實就是一個求餘的過程。

例如,假設對於 100 萬條資料記錄,要做到高速存取,最理想情況是開闢一個連續的空間存放這些資料,減少定址的時間,但很多時候條件並不允許。這個時候我們可以考察一下,系統是否可以提供若干個較小的連續空間,每個空間可以存放一定數量的記錄。比如找到100個較小的連續空間,每個空間可以容納 1 萬條資料連續存放。那麼我們可以採用餘數和同餘定理來設計一個雜湊函式,並實現雜湊表的結構。

這個函式可以如下所示:

f(x) = x mod size
複製程式碼

x表示等待被轉換的數值,size表示有限儲存空間的數量,mod表示取餘操作。通過餘數,你就能將任何數值,轉換為有限範圍內的一個數值,然後據這個新的數值,來確定將資料存放在何處。

而在我們這個例子中,size=100,那麼對於記錄標號分別是 1 和 101 的兩條資料,根據上述公式進行取餘操作,得到的餘數都是 1,那麼它們就會分到同一個儲存的空間中。

這種的做法好處不僅是設定一個存放分類的規則,而且取餘操作簡單快速,不會增加定址時間。

更進一步,如果想增加資料雜湊的隨機程度,可以加入一個較大的隨機數 MAX,如下所示:

f(x) = (x + MAX) mod size
複製程式碼

比如對標號為 1 的記錄,隨機數是590199,那麼計算結果是得到餘數為 0,而標號為 101,隨機數變成 627901,對應餘數是 2。這樣在新的計算公式下,這兩個記錄就分配到不同的儲存空間了。

這種做法更適合需要將資料重新洗牌的應用場景,比如加密演算法、MapReduce 中的資料分發、記錄的高速查詢和定位等。

舉個例子,對於一個加密演算法,如果我們要加密一組三位數,那我們設定一個這樣的加密規則:

  1. 先對每個三位數的個、十和百位數,都加上一個較大的隨機數。
  2. 然後將每位上的數字都除以 7,用所得到的餘數代替原來的三位數;
  3. 最後將第一位和第三位交換。

這就是一個基本的加密變換過程。

例如對數字 625 加密,根據剛剛的規則,隨機數採用 590127,百、十和個位數都分別加上這個隨機數,分別得到的是 590133、590129、590132,接著分別除以 7,得到的餘數分別是 5,1,4,然後交換得到最終的結果是 415。而如果需要解密,因為加密的人會知道加密規則、隨機數和求餘所用的除數 7 以及求餘操作中的商,就可以解密還原回原來的數字。

更多的採用餘數和求餘操作的應用例子:

  • 尾號限行
  • 最大公約數、模冪運算(DES、AES、RSA),凱撒密碼,孫子定理
  • 進位制的轉換,應該說十進位制轉換成其他進位制都是迴圈求餘操作

關於餘數的一些應用例子,你是否還想到其他的應用呢?

可以留言回覆,和我進行交流!


歡迎關注我的微信公眾號--機器學習與計算機視覺,或者掃描下方的二維碼,大家一起交流,學習和進步!

程式設計師的數學筆記2--餘數

相關文章