在C ++中反转偶数的位

时间:2014-12-21 11:44:12

标签: c++ algorithm

一个女孩在棋盘上写N个数字(奇数和偶数),然后,她只修改偶数并反转其二进制表示(从左到右)并替换每个偶数。写一个相同的代码。

0 <= n <= 10^7 

我为此制作了一个代码,我的部分代码如下所示:

            int a[100000];
            while ( t != 0 )   // t is the number in which input is taken
            {
                k = t & 1;
                if ( k == 1 )               
                a[i] = 0;    // a is the array in which bits of new number will be stored
                else
                a[i] = 1;
                i++;
                t = t >> 1; 
            }
            for ( j = i; j >= 0; j-- )
            {
                if (a[j] == 1)
                {
                     num = num + pow(2,j)*a[j];   // num is the number to be formed
                }
            }
                cout<<num<<"\n"; 

但是我的答案对于某些值来说是错误的,例如8,它输出7.这有什么问题?谢谢!

问题链接:

http://www.spoj.com/problems/EC_CONB/

编辑:(回应皮特的回答)

            while ( t != 0 )
            {
                k = t & 1;
                if ( k == 1 )               
                a[i] = 0;
                else
                {
                    a[i] = 1;
                    num = num + pow(2,i);
                }
                i++;
                t = t >> 1; 
            }
            cout<<num<<"\n"; 
        }

这仍然显示相同的问题,将值8输出为7.

3 个答案:

答案 0 :(得分:0)

在递增a[i]后,您似乎正在阅读i,因此行为未定义。

不是创建数组,而是在第一个循环中累积结果。

答案 1 :(得分:0)

阵列?循环?没必要。

反转这样的数字相当于完全反转整数然后右对齐它,就像这样(未经测试)

// reverse from http://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel
// swap odd and even bits
v = ((v >> 1) & 0x55555555) | ((v & 0x55555555) << 1);
// swap consecutive pairs
v = ((v >> 2) & 0x33333333) | ((v & 0x33333333) << 2);
// swap nibbles ... 
v = ((v >> 4) & 0x0F0F0F0F) | ((v & 0x0F0F0F0F) << 4);
// swap bytes
v = ((v >> 8) & 0x00FF00FF) | ((v & 0x00FF00FF) << 8);
// swap 2-byte long pairs
v = ( v >> 16             ) | ( v               << 16);
// right-justify
v /= v & -v;

v应为uint32_t

答案 2 :(得分:0)

问题实际上是要让你反转不反转它们的位。因此,检查if k == 1并将0放入的部分不正确,因为它会反转这些位。

您需要做的是按如下方式反转位的排序:

1000 (8)  -> 0001 (1)
1010 (10) -> 0101 (5)

基于代码的示例代码:

while (t != 0)
{
    k = t & 1;
    // push the output array to the left 
    num <<= 1;
    // add the read bit to the beginning of the output array
    num += k;
    t = t >> 1;
}

说明:

基本思想是我们逐个读取输入数字中的位,并将它们推送到输出数字的开头。

下面是每次迭代时反转数字(1011)的痕迹:

iterations    0       1      2     3    4
input         1011    101    10    1    0
output        0       1      11    110  1101