contributed by < Uduru0522
>
perspective and application of computer systems 2020
Hamming Distance 可以透過計算兩個 string 的相異處數量而得。
由於題目之 x 及 y 長度相同,且 ,
於是我們可以利用 XOR 逕直計算滿足 的 的數量。
計算 x ^ y
之後再透過 mask
以及右移得出 Set Bit, 即為兩數的 Hamming Distance。
Input 為一長度為 numsSize
的 int array,
求陣列中所有 pair 的 Hamming Distance 總和。
測驗一之中我們可以看出來,計算 Hamming Distance 時,可以每個位元分開計算。
因此,可以將問題簡化為 對 numsSize 個 bit 來說,Hamming Distance 為何?,
並進行 32 次 (int 的長度) 這個運算。
接著,由於 Hamming Distance 即是算 (0, 1) 及 (1, 0) 的組數,
當每個 input 只有一個位元時便很好計算:
因此,我們只要對 array 中每個數的每個 bit 都掃過一次即可計算出 Hamming Distance 的總和。
時間複雜度為 。
TODO
觀察程式碼,
可以注意到以下的不等式用來得知一 32-bit 整數是否能被 d() 整除:
經過化簡,可得
接著,考慮三個不同 n 的值:整除、除三餘一、除三於二:
0 (mod 3) | 1 (mod 3) | 2 (mod 3) | |
---|---|---|---|
LHS () | |||
利用 overflow 來取代除法運算中重複減去的過程,節省時間, | |||
其中只有 時, 等式才成立。 |
此等式可以應用於檢測所有 之因數 且 檢測範圍 bit 長度 的
整數的因數上,舉例來說,
若要檢測是否可被 15 整除,M15 即可設成 。
優點: 可提前計算,大幅減少除法運算的次數(僅一次)
程式中字串輸出以『同個字串,不同起點和終點』來輸出,如以下表格:
字串內容 | F | i | z | z | B | u | z | z | %u | \0 |
---|---|---|---|---|---|---|---|---|---|---|
起始點 (included) | Others | |||||||||
終點 (excluded) | Others |
由 div5
以及 div3
兩個值計算出起點以及字串長,div5
div3
將上方表格轉換成數值:
div3 |
div5 |
起點 | length |
---|---|---|---|
0 | 0 | 8 | 1 |
0 | 1 | 4 | 4 |
1 | 0 | 0 | 4 |
1 | 1 | 0 | 8 |
起點方程式
透過觀察,可以發現滿足以下方條件的方程式可以為解:
!div3
便為0div5
會造成除以 2 的效果可得 start_point(div3, div5) = !div3 & (8 >> div5)
。(我的算法)
與題目中解答的相異之處為條件 ㄅ 的處理,題目使用的方式為
『若 div3
,向右移 4-bit』,
無論運算值為何 (8 或 4) 皆會被消除。
length
方程式透過觀察,可以發現滿足以下方條件的方程式可以為解:
div3
和 div5
任一為 1,結果為 4div3
和 div5
同時成立會造成額外乘以 2 的效果可得 length = 2 << div3 << div5
。
考慮到整數 PAGE_QUEUES
可能有以下數值:
給定 size_t offset,計算 blockidx = offset / PAGE_QUEUES
ffs32(n)
根據 Gcc Online Documentation, 6.59 Other Built-in Functions Provided by GCC:
int __builtin_fss(int x)
Returns one plus the index of the least significant 1-bit of x, or if x is zero, returns zero.
此 Macro 與 __builtin__ctz(x)
有類似作用(計算末尾 0 的數量),然而後者對 x == 0
時之應對為 Undefined.
將 offset
以及 divient
皆右移 ffs32(divient)
,消除末尾所有的 0,也就是公因數 。
觀察 PAGE_QUEUES
範圍,看得出可以以 來表示,因此 switch block 僅需處理 3、5、7 三個質因數。
__builtin_ffs()
TODO