位運算總結

位運算符

符號 解釋
& 按位與
按位或
~ 按位異或
<< 左移
>> 右移

原碼、補碼、反碼

補碼=原碼取反+1
例如,-5 二進制數-101; 原碼10000101; 反碼11111010; 補碼11111011

妙用

判斷奇偶數

左移一位相當於乘以2,右移一位相當於除以2

template<class T>  
int Binary_Search(T *x, int N, T keyword)  
{  
    int low = 0, high = N-1,mid;  
    while(low <= high)  
    {  
        mid = (low + high)>>1;//使用位運算代替乘除2可以提高代碼效率
        if(x[mid] == keyword)  
            return mid;  
        if(x[mid] < keyword)  
            low = mid + 1;  
         else  
            high = mid -1;  

    }  
    return -1;  
}  

統計二進制數字中1的個數

相當於JAVA的Integer.bitCount()

int bitCount(int num)
{
    int sum = 0;
    while(num > 0)
    {
        sum += num &1;
        num = num >>1;
    }
    return sum;
}

Swap交換兩個數值的函數

利用位運算可以不用開闢新空間實現交換數值功能
原理是利用異或運算的特性:任意數和自身異或結果爲0,0和任意數異或的結果還是其本身
a = a ^ b,普通的異或
b = b ^ a = b ^ a ^ b,因爲 b ^ b = 0,故 b = a ^ 0,即 b = a;
a = a ^ b ,因爲a在第一行重新賦值,所以a = a ^ b ^ a = b,完成了數值交換

void Swap(int& a, int& b)
{
	a ^= b
	b ^= a
	a ^= b
}

尋找數據列表中只出現一次的數

有一個數據列表,只有一個數出現了1次,其餘N個數都出現了2次。如何不利用額外空間而且在O(n)時間內找到這個只出現一次的數?
還是利用異或的特性

int singleNumber(vector<int>& nums)
{
    if(nums.empty()) return 0;
    int res = 0;
    for(int i : nums)
    {
        res = res ^ i;
    }
    return res;
}

檢查第i位是否爲1

例如要檢查數值num的第3位是否爲1,把1左移3位得到4(100),num & 4的返回值的就是結果

bool isOne(int num, int i)
{
	return num & (1<<i);
}

把第i位改爲1

例如要把數值num的第3位改爲1,把1左移3位得到4(100),num | 4的返回值的就是結果

int alterOne(int num, int i)
{
	return num | (1<<i);
}

另外,num|1相當於num+1;通常用num|1-1求得num最近的偶數

把第i位改爲0

例如要把數值num的第3位改爲0,把1左移3位得到4(100),num & ~4的返回值的就是結果,因爲 ~4的二進制是011

int alterZero(int num, int i)
{
	return num & ~(1<<i);
}

把第i位取反

例如要把數值num的第3位取反,把1左移3位得到4(100),num ^ 4的返回值的就是結果

int alterOpposite(int num, int i)
{
	return num ^ (1<<i);
}

取出一個數的最後一個1

把num左移1位後再進行異或,就會發現如果原數第i位是0,異或就變成1,否則變成0

利用二進制來枚舉子集

給定一組不含重複元素的整數數組 nums,返回該數組所有可能的子集(冪集)。
說明:解集不能包含重複的子集。
輸入: nums = [1,2,3]
輸出:[[3],[1],[2],[1,2,3],[1,3],[2,3],[1,2],[]]

vector<vector<int>> subsets(vector<int>& nums) 
{
    vector<vector<int>> res;
    int len=(1<<nums.size());
    for(int i=0;i<len;++i)
    {
        vector<int> cur;
        for(int j=0;j<nums.size();++j)
        {
            if((i>>j)&1==1) cur.push_back(nums[j]);
        }
        res.push_back(cur);
    }
    return res;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章