位運算總結(持續更新)
阿新 • • 發佈:2021-12-12
字母大小寫‘’高效‘’轉換
日常對leetcode的easy題重拳出擊時發現有道題目709. 轉換成小寫字母的題解有點意思。這道題目雖然簡單,只是將給定的字串中的大寫字母轉小寫返回。但看到題解有人分析了下如何利用位運算進行轉換,這裡簡單分析記錄一下。通過查詢ASCII表可知:
-
大寫字母\(A - Z\)的 ASCII 碼範圍為$ [65, 90]$
-
小寫字母 \(a - z\) 的 ASCII 碼範圍為 \([97, 122]\)
因此常見思路便是先判定字母在$ A - Z \(範圍內後直接ch=ch-'A'+'a'即可,但仔細分析下可以發現\)[65,96]$ 對應的二進位制表示為 \([(01000001)_2, (01011010)_2]\)
ch
的 ASCII 碼與 32進行按位或運算來替代與32 的加法運算。
進一步推廣可得:(ch
為字母)
- 大寫\(\rightarrow\)小寫、小寫\(\rightarrow\)大寫 :
ch ^= 32
- 大寫\(\rightarrow\)小寫、小寫\(\rightarrow\)小寫 :
ch |= 32
- 小寫\(\rightarrow\)大寫、大寫\(\rightarrow\)大寫 :
ch &=-33
可以看出 ASCII 的表設計的非常巧妙,於是我順便看了下c庫函式中的tolower( )
//ctype.h
__forceinline int __CRTDECL __ascii_tolower(int const _C)
{
if (_C >= 'A' && _C <= 'Z')
{
return _C - ('A' - 'a');
}
return _C;
}
判斷奇偶
正常的做法應當是判斷x%2!=0
,但有的時候可能會錯誤的通過x%2==1
判斷。具體原因可見負數取模、取模與取餘
x&1
if (n & 1) {
//奇數
} else {
//偶數
}
很容易理解一個整數為奇數時其二進位制最後一位一定是1,而此時我們只需要將n與\((00...001)_2\)進行一下與運算只考慮最後一位即可簡潔高效的進行判斷。