📜  编写高效的C程序以反转数字的位

📅  最后修改于: 2021-04-27 19:46:51             🧑  作者: Mango

给定一个无符号整数,将其所有位取反,然后用相反的位返回数字。

Input : n = 1
Output : 2147483648  
On a machine with size of unsigned
bit as 32. Reverse of 0....001 is
100....0.

Input : n = 2147483648
Output : 1                          

方法1 –简单
循环访问整数的所有位。如果i / p编号中的第ith位设置为1。然后将该位设置为(NO_OF_BITS – 1)– o / p中的i。其中NO_OF_BITS是给定数字中存在的位数。

/* Function to reverse bits of num */
unsigned int reverseBits(unsigned int num)
{
    unsigned int  NO_OF_BITS = sizeof(num) * 8;
    unsigned int reverse_num = 0, i, temp;
  
    for (i = 0; i < NO_OF_BITS; i++)
    {
        temp = (num & (1 << i));
        if(temp)
            reverse_num |= (1 << ((NO_OF_BITS - 1) - i));
    }
   
    return reverse_num;
}
  
/* Driver function to test above function */
int main()
{
    unsigned int x = 2; 
    printf("%u", reverseBits(x));
    getchar();
}

可以通过取消使用可变温度来优化上述程序。参见下面的修改后的代码。

unsigned int reverseBits(unsigned int num)
{
    unsigned int  NO_OF_BITS = sizeof(num) * 8;
    unsigned int reverse_num = 0;
    int i;
    for (i = 0; i < NO_OF_BITS; i++)
    {
        if((num & (1 << i)))
           reverse_num |= 1 << ((NO_OF_BITS - 1) - i);  
   }
    return reverse_num;
}

时间复杂度:O(n)
空间复杂度:O(1)

方法2 –标准
想法是将num的设置位保持在reverse_num中,直到num变为零为止。在num变为零后,将reverse_num的其余位移位。

令num使用8位存储,num为00000110。循环后,您将得到reverse_num为00000011。现在您需要再将reverse_num左移5次,才能获得精确的反向01100000。

unsigned int reverseBits(unsigned int num)
{
    unsigned int count = sizeof(num) * 8 - 1;
    unsigned int reverse_num = num;
      
    num >>= 1; 
    while(num)
    {
       reverse_num <<= 1;       
       reverse_num |= num & 1;
       num >>= 1;
       count--;
    }
    reverse_num <<= count;
    return reverse_num;
}
  
int main()
{
    unsigned int x = 1;
    printf("%u", reverseBits(x));
    getchar();
}

时间复杂度:O(log n)
空间复杂度:O(1)

方法3 –查找表:
如果我们知道数字的大小,则可以反转O(1)中数字的位。我们可以使用查找表来实现它。有关详细信息,请参考O(1)时间中使用查找表的反向位。

来源 :
https://graphics.stanford.edu/~seander/bithacks.html