我看到了一些解决方案,但它看起来很复杂。
在n,m个位置的两个位之间交换最有效的方法是什么?
int swapBits(int num, int nPostion, int mPosition);
给定整数n,其中我们希望在位置p1和p2交换位:算法:如果两个比特相同,则只返回相同的值,否则使用XOR切换两个比特。
unsigned int swapBits(unsigned int n, unsigned int p1, unsigned int p2)
{
return (((n >> p1) & 1) == ((n >> p2) & 1) ? n : ((n ^ (1 << p2)) ^ (1 << p1)));
}
不确定它是最有效的,但我认为这是一个相当简单的解决方案:
int bitValue(int num, int nPosition)
{
return ( num >> nPosition ) % 2;
}
int swapBits(int num, int nPosition, int mPosition)
{
int nVal = bitValue(num, nPosition);
int mVal = bitValue(num, mPosition);
if (nVal != mVal)
{
if (1 == nVal)
{
num -= 1<<nPosition;
num += 1<<mPosition;
}
else
{
num += 1<<nPosition;
num -= 1<<mPosition;
}
}
return num;
}
以更高效(但可读性较差)的方式提供相同的解决方案:
int swapBits2(int num, int nPosition, int mPosition)
{
int nVal = ( num >> nPosition ) % 2;
int mVal = ( num >> mPosition ) % 2;
if (nVal != mVal)
{
num += (-1)*(2*mVal-1)*(1<<mPosition) + (-1)*(2*nVal-1)*(1<<nPosition);
}
return num;
}
最后:
int swapBits3(int num, int nPosition, int mPosition)
{
int k = ((num >> nPosition) & 1) - (num >> mPosition) & 1;
return num + k*(1<<mPosition) - k*(1<<nPosition);
}
Parth Bera的答案包含一个分支,但xor的想法是正确的。
假设p的比特是CCD_ 1。要把A变成B,把B变成A,我们需要用(A^B)把它们异或。为了方便起见,让X=A^B
????A????B???
0000X0000X000 ^
=============
????B????A???
我们如何生成0000X0000X000
?
????A????B??? >> (nPostion-mPostion)
?????????A??? ^
?????????X??? & (1<<mPosition)
000000000X000 << (nPostion-mPostion)
0000X00000000 +
0000X0000X000 ^
????A????B??? ==
????B????A???
您可以使用以下宏来避免临时变量或堆栈分配,它将适用于任何数字类型:
#define SWAP_BITS(v,b1,b2)
(((v)>>(b1)&1)==((v)>>(b2)&1)?(v):(v^(1ULL<<(b1))^(1ULL<<(b2))))
基于Shay Gold的解决方案,这里有一个修复了一些错误的解决方案:
unsigned int swapBits(unsigned int num, int nPosition, int mPosition) {
unsigned int k = ((num >> nPosition) & 1) - ((num >> mPosition) & 1);
return num + k * ((1U << mPosition) - (1U << nPosition));
}
unsigned int swapbits(unsigned int num, unsigned int pos1, unsigned int pos2) {
unsigned int bits_of_interest_mask = (1 << pos1) | (1 << pos2);
unsigned int bits_of_interest = num & bits_of_interest_mask;
unsigned int null_factor = ((bits_of_interest != 0) & (bits_of_interest != bits_of_interest_mask));
unsigned int xor_mask = null_factor * bits_of_interest_mask;
return num ^ xor_mask;
}
(编译器删除布尔值的乘积:https://godbolt.org/z/a4z3jnh7c,https://godbolt.org/z/aM3TK7bq1)