这是NVIDIA代表在招聘会上提出的一个问题:
写一个小而有效的代码来交换一个字节内的每一对位;例如,10 11 01 10
应该变为01 11 10 01
。
除了通过每个其他索引执行for
循环之外,还有更“有效”的方法吗?我的代码很小,但我想不出这可能比循环更有效“...我猜测可能有办法使用XOR来避免循环,但我不能搞清楚。
谢谢!
答案 0 :(得分:13)
这样的事情应该有效
(i >> 1) & 01010101 + (i << 1) & 10101010
i >> 1
将所有内容向右移1位,& 01010101
只在偶数位置留下位数。
第二部分涉及同一时代的奇数位位置。
不确定它的效率如何。
答案 1 :(得分:12)
您可以使用256条目查找表。
或者,((x & 0x55) << 1) | ((x & 0xAA) >> 1)
。
答案 2 :(得分:2)
如果没有查找表(或者首先生成事物),您还可以:
10 11 01 10
向左移动是01 10 11 00 掩盖10101010给我们00 10 10 00
右移(原始)是 01 01 10 11 用01010101掩盖,给我们01 01 00 01
或我们的结果
01 11 10 01
所以在C或C ++中你可以做到
unsigned char bitswap( unsigned char uch )
{
return ((uch<<1) & 0xAA) | (uch>>1) & 0x55 );
}
只需为0x00到0xff的所有值运行(确保循环终止!)以生成“表”。
答案 3 :(得分:1)
表查找(除非他正在寻找一些特定的NVIDA特定解决方案)。
答案 4 :(得分:1)
对于java ..中的32位整数。
public int swapOddEvenbits(int x)
{
return ( ((x & 0xaaaaaaaa) >> 1 | ((x & 0X55555555) << 1) );
}
如果您使用的是64位,则需要更改掩码..
答案 5 :(得分:0)
由于一个字节中只有256种可能的组合,这似乎是在连续执行速度比初始预计算和/或总内存利用率更重要的任何时候使用基于查找表的解决方案的一个很好的选择。
例如:
lookupTable[00000000] = 00000000
lookupTable[00000001] = 00000010
lookupTable[00000010] = 00000001
...