如何使用位操作輕鬆有效地解決問題

2021-08-27 07:59:43 字數 4784 閱讀 8547

位操作是演算法操作比字短的位或其他資料的行為。需要位操作的計算機程式設計任務包括低階裝置控制,錯誤檢測和糾正演算法,資料壓縮,加密演算法和優化。對於大多數其他任務,現代程式語言允許程式設計師直接使用抽象而不是代表那些抽象的位。執行位操作的源**使用按位運算:and,or,xor,not和位移。

在某些情況下,位操作可以消除或減少迴圈資料結構的需要,並且可以提供多倍的加速,因為並行處理位操作,但**可能變得更難以編寫和維護。 基本

位操作的核心是逐位運算子&(和),| (或),〜(not)和^(exclusive-or,xor)和移位運算子a << b和a >> b。

按位異或沒有布林運算子對應,但有乙個簡單的解釋。異或運算需要兩個輸入,如果其中乙個或另乙個輸入為1,則返回1,但如果兩者都不是,則返回1。也就是說,如果兩個輸入都是1或兩個輸入都是0,則它返回0.按位異或 - 與插入符號的運算子^,對每對位執行異或操作。獨佔或通常縮寫為xor。

例子

計算給定數字的二進位制表示中的1的數量

int count_one(int

n) return count;

}

是4的冪(實際上地圖檢查,迭代和遞迴方法可以做同樣的事情)

boolispoweroffour(intn)
^技巧

使用^刪除甚至完全相同的號碼,儲存奇,或儲存在不同的位並移除相同。

兩個整數之和

使用^&新增兩個整數

intgetsum(inta,intb)
遺失號碼

給定乙個包含n個不同數字的陣列,取自0,1,2,...,n,找到陣列中缺少的數字。例如,給定nums = [0,1,3]返回2.(當然,你可以通過數學來做到這一點。)

intmissingnumber(vector<int>& nums)returnret^=nums.size();

}

|技巧

保持盡可能多的1位

找到2的最大冪(二進位制形式的最高有效位),其小於或等於給定數量n.

long largest_power(long n)
反向位元

給定32位無符號整數的反轉位。 解

uint32_treversebits(uint32_tn)returnres;

}

uint32_treversebits(uint32_tn)returnret;

}

&技巧

只選擇某些位

反轉整數字

x = ((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1);

x = ((x & 0xcccccccc) >> 2) | ((x & 0x33333333) << 2);

x = ((x & 0xf0f0f0f0) >> 4) | ((x & 0x0f0f0f0f) << 4);

x = ((x & 0xff00ff00) >> 8) | ((x & 0x00ff00ff) << 8);

x = ((x & 0xffff0000) >> 16) | ((x & 0x0000ffff) << 16);

數字範圍的按位and

給定範圍[m,n],其中0 <= m <= n <= 2147483647,返回此範圍內所有數字的按位and,包括端值。例如,給定範圍[5,7],您應該返回4。 解

intrangebitwiseand(intm,intn)returnm<
1位數

編寫乙個帶無符號整數的函式,並返回它所具有的「1」位數(也稱為漢明權重)。 解

int hammingweight(uint32_t n) 

return count;

}

inthammingweight(uint32_t n)returncount;

}

應用

重複的dna序列

所有dna由一系列縮寫為a,c,g和t的核苷酸組成,例如:「acgaattccg」。在研究dna時,有時識別dna中的重複序列是有用的。編寫乙個函式來查詢dna分子中不止一次出現的所有10個字母長的序列(子串)。

例如,給定s =「aaaaacccccaaaaaccccccaaaaagggttt」,

返回:[「aaaaaccccc」,「cccccaaaaa」]。 解

classsolution;inthashkey = 0;for(inti = 0; i < 9; ++i) hashkey = (hashkey<<2) | (s[i]-'a'+1)%5;for(inti = 9; i < slen; ++i)returnv;

}};

但是當重複序列出現太多次時,上述解決方案可能無效,在這種情況下我們應該用這裡unordered_mapkeymap替換char keymap[1<<21]

多數元素

給定大小為n的陣列,找到多數元素。多數元素是出現超過⌊n /2⌋倍的元素。(位元計算通常的方式,但在這裡我們實際上也可以採用排序和摩爾投票演算法) 解

int majorityelement(vector& nums)returnret;

}

單號iii

給定乙個整數陣列,除了乙個元素外,每個元素都會出現三次。找到那乙個。(這種型別仍然可以通過位計數來輕鬆解決。)但我們將通過它來解決它digital logic design

//inspired by logical circuit design and boolean algebra;

//counter - unit of 3;

//current incoming next

//a b c a b

//0 0 0 0 0

//0 1 0 0 1

//1 0 0 1 0

//0 0 1 0 1

//0 1 1 1 0

//1 0 1 0 0

//a = a&~b&~c + ~a&b&c;

//b = ~a&b&~c + ~a&~b&c;intsinglenumber(vector

<int>& nums)returna | b;

};

字長的最大乘積

給定乙個字串陣列字,找到length(word [i])* length(word [j])的最大值,其中兩個字不共享公共字母。您可以假設每個單詞僅包含小寫字母。如果不存在這兩個單詞,則返回0。

示例1:

給定[「abcw」,「baz」,「foo」,「bar」,「xtfn」,「abcdef」] 

返回16 

這兩個單詞可以是「abcw」,「xtfn」。

例2:給定[「a」,「ab」,「abc」,「d」,「cd」,「bcd」,「abcd」] 

返回4 

這兩個詞可以是「ab」,「cd」。

例3:給定[「a」,「aa」,「aaa」,「aaaa」] 

返回0 

沒有這樣的一對單詞。

由於我們將非常頻繁地使用單詞的長度,我們要比較兩個單詞的字母,檢查它們是否有一些共同的字母:

intmaxproduct(vector<string>& words)

如何有效地解Bug RED方法

解bug應當是修復 中的缺陷,而不只是隱藏起來 譯註 解bug時常發生分析時總感覺快找到答案了,而後面卻一再陷入僵局。比如,將執行緒同步問題引起的一些時而有,時而沒有的問題。分析時可能會認為這是個典型的執行緒同步問題,a執行緒沒有按照預期的方式改變某個變數,導致了b執行緒處理出錯。這樣的分析結果如果...

如何有效地解Bug (RED方法)

譯註 解bug時常發生分析時總感覺快找到答案了,而後面卻一再陷入僵局。比如,將執行緒同步問題引起的一些時而有,時而沒有的問題。分析時可能會認為這是個典型的執行緒同步問題,a執行緒沒有按照預期的方式改變某個變數,導致了b執行緒處理出錯。這樣的分析結果如果沒有除錯 debug 的支援,就有可能將開發者帶...

如何更有效地使用kindle?

kindle入手很久了,有段時間棄用了,主要原因是電子書分類管理不方便,讀書過程中做的標註或者記錄的筆記無法匯出,使用郵箱傳書籍多次無緣無故的失敗,使用者體驗比多看確實要差不少,但是又不想破壞原生系統,所以在網上找了半天,找到一些輔助的工具和方法,對於之前的不足之處能夠有些改善,現將其總結如下,供各...