最近想做乙個通用二分法,所謂通用,就是對不同的位寬的資料都能做二分法,比如輸入4bit。能夠按照8->12->14->13的順序開始做二分法。輸入2bit,能夠按照2->3的順序做二分法。
假設輸入n,那麼就會從n/2開始做二分法。
使用verilog語言實現的話,我這裡暫時想出了一種思路。
以下面這個二分法流程為引。
程序cnt_id=0 : 比較結果為0表示二分法向下 32->1610
0000->01
0000
程序cnt_id=1 : 比較結果為1表示二分法向上 16->24 010
000-> 011
000
程序cnt_id=2 : 比較結果為0表示二分法向下 24->20 0110
00-> 0101
00
程序cnt_id=3 : 比較結果為0表示二分法向下 20->18 01010
0-> 01001
0
程序cnt_id=4 : 比較結果為1表示二分法向上 18->19 010010
-> 010011
根據以上這個流程可以總結出幾點規律:
1 每次做二分法的資料位寬只有2bit,其他bit都不變。
2 做二分法的資料位置,根據程序變化。比如程序是0時,資料只有最高位和次高位變化。資料操作依次右移。
3 做二分法的2bit資料中,高位會與比較結果相等,低位的結果都是從0變成1。
那麼,我的思路是做乙個資料刷子,這個刷子把原資料刷一下,就變成了二分之後的資料。
這個刷子是這麼做的。
首先根據異或xor的運算規則。
根據0 ^ 0 = 0,0 ^ 1 = 1 可得0 ^ n = n
根據1 ^ 0 = 1,1 ^ 1 = 0 可得1 ^ n = !n
那麼以此運算規則為基礎,根據上面總結的二分法的規律,資料bit不變的地方,我讓它異或0,bit變為比較結果的地方,我讓他異或(比較結果的取反),從0變成1的地方,我讓它異或1就可以了。
所以我構造的刷子就出來了。
[!cmp_in,1』b1]根據cnt_id右移位,其他位補0
用這個刷子,去異或原資料,比如
程序cnt_id=0 : 比較結果為0表示二分法向下 32->1610
0000(->01
0000)
我的刷子是110000,那麼110000異或100000是010000。
程序cnt_id=1 : 比較結果為1表示二分法向上 16->24 010
000 (->011
000)
我的刷子是001000,那麼001000異或010000是011000。
依次類推。
寫成**我是這麼寫的
result <= result ^ (<<(reg_width-2-cnt_id))
空位的話verilog會自動補0的。
我這個思路其實我自己感覺還有些奇怪的地方,比如這句話是不是邏輯過多的。
先記錄一下,以後有問題再回來總結。
通用二分查詢
這是極其簡單的乙個演算法,正是因為其簡單,我經常被其搞死。不管是在比賽時還是在面試時,我都在這上面栽過跟頭。因為其簡單,所以總也不願花過多時間來寫它,總想一氣呵成,但總也呵不成,於是腦袋越來越混亂,情緒越來越激動,於是悲劇隨之而來。二分查詢要求被查詢陣列是排好序的陣列,其時間複雜度為o log n ...
數字配對(二分)
給出一組數,驗證這些數中是否有兩個數的和為s 多組資料,每組資料兩行,第一行是兩個整數,n n 100,000 和s 0 s 2 32 第二行將有n個整數a1,a2,an 0 ai 2 32,1 i n 數字之間用空格隔開。每組資料輸出一行,僅乙個數字,代表有多少不同的有序數字對 ai,aj 使得a...
c語言實現的通用二分查詢演算法
cpp 二分查詢是基於排好序的演算法。複雜度低,並且很高效,由於專案中大量使用的了二分查詢,但是又不能每個業務實現乙個 因此有必要實現乙個通用的二分查詢 其主要思想 通過對已經排好序的陣列,進行資料指標的比較。const void key 需要查詢的key值 const void base,所要查詢...