c++ 输出二进制_【位运算与状态压缩】二进制的魅力
【引言】
????????今天講講位運算與狀態壓縮。
????????位運算涉及系統底層的運算,騷操作很多;狀態壓縮則是編程中空間優化的有效手段,應該說兩者本身其實并沒有太直接的聯系,但是在實際使用時會有一定的結合,所以還是放到一起講。
【位運算介紹】
? ? ? ? 我們知道程序中的所有數字(不止數字,包括圖片、視頻等任何元素)在計算機內存中都是以二進制的形式儲存的,而位運算就是直接對二進制進行操作。
計算機中的數字都以二進制的形式存儲
????????聽起來似乎很高大上,事實上用起來很簡單,我們先看看常見的兩個位運算:"按位與(&)"、"按位或(|)"
例.
a?=?5;?b?=?6
print(a?&?b)
print(a?|?b)
輸出結果:
4
7
為什么是這個結果?
因為系統中:
????????????????"5"的二進制是"101"
????????????????"6"的二進制是"110"
而其運算方式是"一位一位"地算(都叫位運算了嘛)。
首先是"按位與":
? ? ? ? ?1? 0? 1
?&? ? ?1? 1? 0
——————
? ? ? ? ?1? 0? 0
可以注意到每一位都是按照"與"地方式計算的,即:
????????1 & 1 → 1
????????0 & 1→ 0
????????1 & 0→ 0
接下來是"按位或":
同理,每一位都進行"或運算",得到"111"。
????????這就是位運算,每一個二進制位進行相應的運算得到結果(C++入門被&和&&兩個符號坑過的舉爪...)。
PYTHON3中常用位運算有6種,包括:
????按位與(&):運算時,都為1則為1,否則0
????按位或(|):其中一個為1時則結果1,否則0
????按位異或(^):不同為1,相同為0
????按位取反(~):每一位進行0和1的變換
????左移(<向右移動N位,高位補0,低位去掉
????右移(>>):向左側移動N位,高位去掉,低位補0
①按位與:
????????5 & 6 → 4
②按位或:
????????5 | 6 → 7
③按位異或:
????????5 ^ 6 → 3
④按位取反:
????????~5 → 2
⑤左移:
????????5 << 1 → 1
⑥右移:
????????5 >> 1 → 2
位運算的騷操作:結合位運算,可以優化許多功能
①將整數x整除2或乘以2:
x >> 1 即整除2
x << 1 即乘以2
這里用到了二進制的原理,由于位運算是相對更為底層的運算,所以速度更快
②將整數x在二進制的右數第k位取反:
x ^ (1<
例. 將數字7在二進制下的第2位取反,則:
????????7 ^ (1<
????????即,(111)2 ^ (10)2 → (101)2
(什么?你問這個操作有什么用?該有用時自會有用,,,)
③獲取整數x在二進制下的最低位的1(即最右邊的1):
????????x&-x(樹狀數組專用,暫時不解釋了)
④將整數x在二進制下最低位的1變成0:
????????x = x&(x-1)
一般用于求解x在二進制下1的個數,例.
a?=?5;?c?=?0
while?a>0:
????a?=?a?&?a-1
????c?+=?1
print(c)
輸出為2,因為5的二進制是101,第一次先將最右邊的1變為0,則101→100,第二次循環繼續將最右邊的1變為0,則100→000,循環結束。
差不多常用的就這些了。
【狀態壓縮介紹】
????????又是一個聽起來很厲害實際上不是太難(但也可以難上天)的算法。說白了,就是用一個十進制數表示一個集合的狀態。
????????例如,有5盞燈,這5盞燈有的開著,有的關閉,我們就可以用一串0和1來表示這5盞燈(1表示開,0表示關),則看為二進制數就是10110,即22。
這樣一來,我們可以用22表示當前5盞燈的狀態,免去了數組的存儲,在空間上進行了優化,也給映射之類的操作提供了方便(比如可以將這些狀態作為數組下標處理)。
那么如果某一盞燈變化了狀態怎么辦?
還記得位運算的第2個騷操作么,例如左數第四盞燈如果關閉了,則只需將二進制下的右數第二位取反即可,也就是22^(1<,即二進制下的10100。
????????狀態壓縮本質是利用二進制表示一個集合的狀態(當然如果狀態種類比較多,則可能有三進制、四進制甚至更多,例如5個人玩石頭剪刀布,則每一組方案需要利用3進制表示,因為每個人有石頭剪刀布三種狀態)。而狀態改變時就需要操作對應的十進制數,也就是利用到位運算了。
????????狀態壓縮最常見的應用是與動態規劃的結合,這不是本篇的重點,關于狀壓動規還是先挖個坑吧,是挺有意思的算法。
????????另一個冷門應用就是二進制枚舉法,詳見之前的文章:二進制枚舉法
總結
以上是生活随笔為你收集整理的c++ 输出二进制_【位运算与状态压缩】二进制的魅力的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 竹藤家具怎么样
- 下一篇: WIFI认证请求被拒绝接入认证被拒绝怎么