原文
簡化版 複習用
問題需求:計算32位整型數中的'1'的個數
思路分析:
1.整型數 i 的數值,實際上就是各位乘以權重——也就是乙個以2為底的多項式:
i = a0*2^0+a1*2^1+a2*2^2+...
因此,要求1的位數,實際上只要將各位消權:
i = a0+a1+a2+...
所得的係數和就是'1'的個數。
2.對任何自然數n的n次冪,用n-1取模得數為1,證明
若 n^(k-1) % (n-1) = 1 成立
則 n^k % (n-1) = ((n-1)*n^(k-1) + n^(k-1)) % (n-1) = 0 + n^(k-1) % (n-1) = 1 也成立
又有 n^(1-1) % (n-1) = 1
故對任意非負整數n, n^n %(n-1)=1
3.因此,對乙個係數為的以n為底的多項式p(n), p(n)%(n-1) = (sum()) % (n-1) ;
如果能保證sum() < (n-1),則 p(n)%(n-1) = (sum()) ,也就是說,此時只要用n-1對多項式取模,就可以完成消權,得到係數和。
於是,問題轉化為,將以2為底的多項式轉化為以n為底的多項式,其中n要足夠大,使得n-1 > sum()恆成立。
32位整型數中ai=0或1,sum()<=32。n-1 > 32 ,n需要大於33。
因此取n=2^6=64>33作為新多項式的底。
4.將32位二進位制數的每6位作為乙個單位,看作以64為底的多項式:
i = t0*64^0 + t1*64^1 + t2*64^2 + t3*64^3 + ...
各項的係數ti就是每6位2進製數的值。
這樣,只要通過運算,將各個單位中的6位數變為這6位中含有的'1'的個數,再用63取模,就可以得到所求的總的'1'的個數。
5.取其中任意一項的6位數ti進行考慮,最簡單的方法顯然是對每次對1位進行mask然後相加,即
(ti>>5)&(000001) + (ti&>>4)(000001) + (ti>>3)&(000001) + (ti>>2)&(000001) + (ti>>1)&(000001) + ti&(000001)
其中000001位2進製數
由於ti最多含有6個1,因此上式最大值為000110,絕不會產生溢位,所以上式中的操作完全可以直接對整型數 i 進行套用,操作過程中,t0~t6將並行地完成上式的運算。
注意:不能將&運算提取出來先+後&,想想為什麼。
因此,bit count的實現**如下:
[cpp]view plain
copy
intbitcount(unsigned
intn)
但mit hakmem最終的演算法要比上面的**更加簡單一些。
為什麼說上面的式子中不能先把(ti>>k)都先提取出來相加,然後再進行&運算呢?
因為用&(000001)進行mask後,產生的有效位只有1位,只要6位數中的'1'個數超過1位,那麼在"先加"的過程中,得數就會從最低位中向上溢位。
但是我們注意到,6位數中最多只有6個'1',也就是000110,只需要3位有效位。上面的式子實際上是以1位為單位提取出'1'的個數再相加求和求出6位中'1'的總個數的,所以用的是&(000001)。如果以3位為單位算出'1'的個數再進行相加的話,那麼就完全可以先加後mask。演算法如下:
tmp = (ti>>2)&(001001) + (ti>>1)&(001001) + ti&(001001)
(tmp + tmp>>3)&(000111)
c**:
[cpp]view plain
copy
intbitcount(unsigned
intn)
注:**中是使用8進製數進行mask的,11位8進製數為33位2進製數,多出一位,因此第一位八進位制數會把最高位捨去(7->3)以免超出int長度。
從第乙個版本到第二個實際上是乙個「提取公因式」的過程。用1組+, >>, &運算代替了3組。並且已經提取了"最大公因式"。然而這仍然不是最終的mit hakmem演算法,不過已經非常接近了,看看**吧。
mit hakmem演算法:
[cpp]view plain
copy
intbitcount(unsigned
intn)
又減少了一組+, >>, &運算。被優化的是3位2進製數「組」內的計算。再回到多項式,乙個3位2進製數是4a+2b+c,我們想要求的是a
+b+c,n>>1的結果是2a+b,n>>2的結果是a。
於是: (4a+2b+c) - (2a+b) - (a) = a + b + c
中間的mask是為了遮蔽"組間""串擾",即遮蔽掉從左邊組的低位移動過來的數
MIT HAKMEM演算法分析
今天學習了一種很有趣的bitcount演算法 mit hakmem演算法。本文中 表示乘方 問題需求 計算32位整型數中的 1 的個數 思路分析 1.整型數i 的數值,實際上就是各位乘以權重 也就是乙個以2為底的多項式 i a0 2 0 a1 2 1 a2 2 2 因此,要求1的位數,實際上只要將各...
演算法分析 演算法的漸進效率分析
一般用於界定函式集合的上界,漸進表示式o g n 的含義就是,c為正常數,函式集合o中的元素的最大值不會超過c.g n f n o g n 的含義是,函式f n 的屬於集合o g n 因為函式集合o中的最大值為c.g n 所以f n 的最大值為c.g n 由於只是漸進的上界,所以當函式g n 的階數...
演算法和演算法分析
一 演算法的基本概述 演算法是為了解決某類問題而規定的乙個有限長的操作序列。乙個演算法必須滿足以下五個重要特性 1 有窮性2 確定性3 可行性 4 有輸入5 有輸出 二 設計演算法的原則 1.正確性 2.可讀性 3 健壯性 4.高效率與低儲存量需求 三 演算法的時間複雜度簡介 語句頻度 語句重複執行...