2020q3 Homework4 (quiz4)
contributed by < shauming1020
>
測驗 1
population count 簡稱 popcount 或叫 sideways sum,是計算數值的二進位表示中,有多少位元是 1
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
- Hamming Distance 計算兩數之間相異 bit 個數, 先將相異的 bit 位置設為 1 後再透過 __builtin_popcount 求出 1 的個數,即為 Hamming Distance
- 不使用 gcc extension 的 C99 實作程式碼
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
LeetCode 477. Total Hamming Distance
先從較直覺的暴力法著手,numsSize 不斷增長的情況下,時間複雜度為
nums[i] |
bit 3 |
bit 2 |
bit 1 |
bit 0 |
4 |
0 |
0 |
0 |
1 |
14 |
1 |
1 |
1 |
0 |
2 |
0 |
0 |
1 |
0 |
1s |
1 |
2 |
2 |
0 |
0s |
2 |
1 |
1 |
3 |
sum |
2 |
2 |
2 |
0 |
可以推得總和為所有資料中相對 bit 的 1 總數 * 0 總數,因此
研讀錯誤更正碼簡介及抽象代數的實務應用
研讀錯誤更正碼簡介及抽象代數的實務應用,摘錄其中 Hamming Distance 和 Hamming Weight 的描述並重新闡述,舉出實際的 C 程式碼來解說;
搭配閱讀 Hamming codes, Part I 及 Hamming codes, Part II,你可適度摘錄影片中的素材,但應當清楚標註來源
Hamming Distance & Hamming Weight
- 定義
- Hamming Distance : 兩向量有幾個相異的 bit
e.g.
- Hamming Weight : 一個向量不是 0 的的地方有幾個
e.g.
- x 和 x' 的 Hamming Distance 只是 (x + x') 的 Hamming Weight
- minimum distance : 在這個碼中,任兩不同 codewords 的 Hamming distance,其當中最小值
- minimum weight : 所有不為 0 的 codewords,其 Hamming weight 的最小值
- 特性
- 由於兩個 codewords 的 Hamming distance 會等於相加後的 Hamming weight,所以對線性碼來說,,也就是 minimum distance 會等於 minimum weight
- 要改 t 個錯,其 minimum distance 至少要
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
- 球心 (x, x') 為一個 codeword,球包含所有跟此 codeword 的 Hamming distance <= t 的 binary vectors
- 由於要改 t 個錯,兩球不能交疊在一起,否則交疊的 vectors 不知道要改成 x 還是 x'
- 因此兩球距離至少為 1,即任兩 codewords 距離至少要
研讀 Reed–Solomon error correction
測驗 2
給你一棵樹,樹上有 n 個節點,編號自 0 到 。樹以父節點陣列的形式提供,其中 parent[i] 是節點 i 的父節點。樹的根節點是編號為 0 的節點。
請設計 treeAncestorGetKthAncestor(TreeAncestor *obj, int node, int k) 函式,回傳節點 node 的第 k 個祖先節點。若不存在這樣的祖先節點,回傳 -1。樹節點的第 k 個祖先節點是從該節點到根節點路徑上的第 k 個節點
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
treeAncestorCreate
#11 obj->parent = malloc(n * sizeof(int *));
從這行可以知道結構體成員 parent 為 a pointer to a pointer,故 AAA 為 int ** parent
#13 int max_level = 32 - __builtin_clz(n) + 1;
計算最大樹高 (skewed)
-
初始化 obj ,index i 表示節點編號,index j 存取上 代祖先,因此
obj->parent[i][j] = -1;
先將每個節點的每 代祖先設為 -1 (沒有祖先)
-
每個節點的上一代 ( j = 0 ) 祖先根據給定的 parent 序列逐一指派,例如 parent 給定 [-1,0,0,1,1,2,2],則第 0 個節點的上一代祖先將被指派為 -1
-
接著建立上 代祖先,j 從 1 開始,當存在上 代祖先時,才會有上 代祖先,因此 BBB = -1
treeAncestorGetKthAncestor
- 搜尋上 k 代祖先,如果上 代祖先存在,就從上 代祖先繼續往上搜尋
- 例如 k = 5 (0b101),則 i 在 0、2 時可能會有上 代祖先存在,如果上 代祖先存在,則從上一代祖先繼續往上搜尋上 祖先
測驗 3
從 1 數到 n,
如果是 3的倍數,印出 “Fizz”
如果是 5 的倍數,印出 “Buzz”
如果是 15 的倍數,印出 “FizzBuzz”
如果都不是,就印出數字本身
- 從
strncpy(fmt, &"FizzBuzz%u"[(MSG_LEN >> KK1) >> (KK2 << KK3)], length);
可以回推程式想執行的事情
- 從 "FizzBuzz%u" 中取出特定長度的字串出來放到變數 fmt,再將其打印出來
- 而要取多長則取決於變數 length,從哪裡開始取則取決於 (MSG_LEN >> KK1) >> (KK2 << KK3) ,其中 MSG_LEN 8
unsigned int length = (2 << div3) << div5;
- 從 1 數到 n ,如果可以被 3 整除則 div3 將被設成 1,否則為 0 ,同理 div 5
- 因此我們會得到下列四種不同的 length
- 3 的倍數,(2 << 1) << 0 得 4
- 5 的倍數,(2 << 0) << 1 得 4
- 15 的倍數,(2 << 1) << 1 得 8
- 都不是,(2 << 0) << 0 得 2
(MSG_LEN >> KK1) >> (KK2 << KK3)
根據以上不同的情境將未知的 KK 填入
- 先考慮 3 和 15 的倍數,要印出 “Fizz” 和 “FizzBuzz” 都得從字串的 0 位開始取,先從選項中取固定常數出來嘗試
- KK1 = 1、KK2 = 2、KK3 = 2,可得 0
- 接著考慮 5 的倍數,要印出 “Buzz” 得從字串的 4 位開始取
- 而最後考慮都不是的情況,要取得字串的輸出控制符 %u 得從字串的 8 位開始取
測驗 4
考慮到整數 PAGE_QUEUES 可能有以下數值:
(1 or 2 or 3 or 4)
(5 or 6 or 7 or 8) × (), n from 1 to 14
其中 CASES 可能形如:
用最少的 case-break 敘述做出同等 size_t blockidx = offset / PAGE_QUEUES;
效果的程式碼
__builtin_ffs(x))
表示 x 二進位中最後一個 1 的位置
int __builtin_ffs (unsigned int x)
Returns one plus the index of the least significant 1-bit of x, or if x is zero, returns zero.
ffs32(x) ((__builtin_ffs(x)) - 1)
等同於 ctz ,表示尾端有幾個 0,即該數是否含有
blockidx = offset >> ffs32(divident);
,先從 offset 提出
divident >>= ffs32(divident);
- 將 提出後且 PAGE_QUEUES 最多為 ,故只需判斷
blockidx /= y
,y = 2, 3, 5, 7 質數即可