📜  位操作(重要策略)

📅  最后修改于: 2021-05-04 20:07:05             🧑  作者: Mango

先决条件:C语言中的按位运算符,竞争性编程的按位hacks,竞争性编程的bit技巧

  1. 计算从1到n的XOR(直接方法):
    // Direct XOR of all numbers from 1 to n
    int computeXOR(int n)
    {
        if (n % 4 == 0)
            return n;
        if (n % 4 == 1)
            return 1;
        if (n % 4 == 2)
            return n + 1;
        else
            return 0;
    }
    
    Input: 6
    Output: 7
    

    有关详细信息,请参考从1到n的Compute XOR。

  2. 我们可以快速计算出小于或等于和与XOR相等的数字的组合总数。无需使用循环(蛮力法),我们可以通过数学技巧直接找到它,即
    // Refer Equal Sum and XOR for details.
    Answer = pow(2, count of zero bits)
  3. 如何知道数字是否为2的幂?
    //  Function to check if x is power of 2
    bool isPowerOfTwo(int x)
    {
         // First x in the below expression is
         // for  the case when x is 0 
         return x && (!(x & (x - 1)));
    }
    

    有关详细信息,请参阅检查数字是否为2的幂。

  4. 查找集合中所有子集的XOR。我们可以在O(1)时间内完成。如果给定集合具有多个元素,则答案始终为0。对于具有单个元素的集合,答案是单个元素的值。有关详细信息,请参考所有子集的XOR。
  5. 我们可以使用GCC在C++中以整数的二进制代码快速找到前导,尾随零和1的数目。可以通过使用内置函数来完成,即
    Number of leading zeroes: builtin_clz(x)
      Number of trailing zeroes : builtin_ctz(x)
      Number of 1-bits: __builtin_popcount(x) 

    有关详细信息,请参阅GCC内置函数。

  6. 将二进制代码直接转换为C++中的整数。
    // Conversion into Binary code//
    #include 
    using namespace std;
      
    int main()
    {
        auto number = 0b011;
        cout << number;
        return 0;
    }
    
    Output: 3
    
  7. 交换两个数字的最快方法:
    a ^= b;
    b ^= a; 
    a ^= b;

    有关详细信息,请参考交换两个数字。

  8. 翻转数字位的简单方法:可以通过简单的方法完成,只需从所有位均等于1时获得的值中减去数字即可。
    例如:
    Number : Given Number
    Value  : A number with all bits set in given number.
    Flipped number = Value – Number.
    
    Example : 
    Number = 23,
    Binary form: 10111;
    After flipping digits number will be: 01000;
    Value: 11111 = 31;
    
  9. 我们可以找到O(1)时间中固定大小整数的最高有效设置位。例如,下面的cocde用于32位整数。
    int setBitNumber(int n)
    {      
        // Below steps set bits after
        // MSB (including MSB)
      
        // Suppose n is 273 (binary 
        // is 100010001). It does following
        // 100010001 | 010001000 = 110011001
        n |= n>>1;
      
        // This makes sure 4 bits
        // (From MSB and including MSB)
        // are set. It does following
        // 110011001 | 001100110 = 111111111
        n |= n>>2;   
      
        n |= n>>4;  
        n |= n>>8;
        n |= n>>16;
          
        // Increment n by 1 so that
        // there is only one set bit
        // which is just before original
        // MSB. n now becomes 1000000000
        n = n + 1;
      
        // Return original MSB after shifting.
        // n now becomes 100000000
        return (n >> 1);
    }
    

    有关详细信息,请参见查找数字的最高有效置位。

  10. 我们可以快速检查数字中的位是否处于备用模式(例如101010)。我们计算n ^(n >> 1)。如果n具有备用模式,则n ^(n >> 1)运算将产生仅具有设置位的数字。 ‘^’是按位XOR运算。有关详细信息,请参考检查数字是否具有备用模式中的位。