给定一个整数,n。倒数这个数字的最快方法是什么?例如,如果n = 5(101),则输出应为2(010)。不会将前缀0
视为反向。这个问题的独特之处在于,我们不会考虑前缀0
。
我的方法:
Convert n to binary as a string. For example, if n = 5 then I'll have string, say str, as `101`.
Convert 1 to 0 and 0 to 1 in the string. (output: 010)
Convert resultant binary string to number. (output: 2)
更多输入/输出示例:
Input: 7, Output: 0
Input: 8, Output: 7
Input: 10, Output: 5
Input: 98, Output: 29
正如您所看到的,我的方法看起来很幼稚或效率很低。有没有更好的方法,通过使用一些位操作操作或任何其他方式更快地获得所需的输出?
注意: n
也可能是否定的!对于负数,必须考虑2的补码以反映这些位。
我不是要求确切的代码。伪代码或方法会有所帮助。
答案 0 :(得分:2)
这个问题是可互联的(带有按位XOR指令的开销),其问题是将n舍入到最小数量的形式2 ^ k-1。对于32位int n,您可以为后者调整其中一个标准位:
m = n;
m |= m >> 1;
m |= m >> 2;
m |= m >> 4;
m |= m >> 8;
m |= m >> 16;
return m ^ n;
答案 1 :(得分:1)
unsigned reversed = 0;
while (num := 0) {
reversed = reversed << 1;
reversed |= (num & 1);
num = num >> 1;
}
将低阶位移出原始位置,或者在反转时将它们移位到连续的高位。
答案 2 :(得分:1)
flip(n)= 2 ^(ceiling(lg(n))) - 1 - n,其中lg是对数基数2.
如果您知道n的最大设置位,那么您可以通过获取最大设置位并将1向左移1来快速获得2 ^ ceiling(lg(n))。
答案 3 :(得分:0)
如果表现真的很重要,你可以制表。
从MSB到LSB逐字节处理整数。如果该字节为空,则跳过。否则,使用256个条目(带前缀)的预计算查找表,以及后续字节,XOR。
if (B[0]) { B[0]= LUT[B[0]]; B[1]^= 255; B[2]^= 255; B[3]^= 255; }
else if (B[1]) { B[1]= LUT[B[1]]; B[2]^= 255; B[3]^= 255; }
else if (B[2]) { B[2]= LUT[B[2]]; B[3]=^255; }
else B[3]= LUT[B[3]];
您还可以使用适当的掩码一次性对32位进行异或。
答案 4 :(得分:0)
~n
没有给出预期结果的原因是您号码中的所有前导零。要在将它们反转为1之后屏蔽这些零,直接的方法是:
m = abs(n);
result = ~m & (int)(exp2(ceil(log2(m)))-1);
通过获取(正)输入的base-2对数,生成正确长度的掩码。 n
为2的幂的边界情况是正确的,因为结果中的前导1
始终为0
,因此将其从掩码中排除无关紧要。
性能可能是公平的,但编码简洁。