我正在准备编程面试。因此,我试图解决一些过时的面试问题,以便为即将到来的面试做好准备。我被困在解决以下问题:
30位无符号整数X的循环右移是通过将X的二进制表示的所有位右移一个位置并将最高有效位移动到最低有效位而获得的数。确切地说,如果X的二进制表示是
X29 X28 ... X2 X1 X0
X的右循环移位的二进制表示是
X28 ... X2 X1 X0 X29
例如,给定数字X(为了可读性而添加的数字内空格):
<00> 00 0000 0000 0000 0000 0100 1100 0001BIN = 1217DEC正确的循环移位
<00> 00 0000 0000 0000 0000 1001 1000 0010BIN = 2434DEC。可以重复循环移位操作,例如给定相同的X值,其右循环移位为3:
<00> 00 0000 0000 0000 0010 0110 0000 1000BIN = 9736DEC写一个函数
int largest_right_cyclic_shift(int n);
给定30位无符号整数X的找到具有最大值的右循环移位。例如,值X = 1217DEC的52的右循环移位是809500676DEC,这是X的最大可能的30位右循环移位:
11 0000 0100 0000 0000 0000 0000 0100BIN = 809500676DEC
因此,给定X = 1217,函数应返回52.如果有许多正确的循环移位产生最大值,则函数应返回其中任何一个。您可以假设参数X始终是30位无符号整数。
这是我的答案:
#include <algorithm>
int largest_right_cyclic_shift ( int n ) {
long m = n;
long max = n;
int shift = 0;
for (int i = 1; i < 30; i++){
m = n << i;
if (m > max){
max = m;
shift = i;
}
}
return shift;
}
输入数字1217的预期答案是22.但是上面的代码给了我一个23的值。我知道错误是因为我将输入表示为32位整数,而在问题中指出我有将输入表示为30位整数。使用32位整数表示30位整数将左侧最左边的2位数字保留为0.因此,当我们执行左移位运算符时,它将移位位31 ,而不是移位第29位。
解决此问题的最佳方法是什么?我确信解决方案很简单,只需要一些关于位移的知识。
由于
答案 0 :(得分:4)
解决此问题的最佳方法是什么?
m = (n << i) & 0x3fffffff;
答案 1 :(得分:2)
FredOverflow的评论应该是正确答案。
def largest(n) :
mx = n
p = 0
for i in range(30) :
m = n<<i & 0x3fffffff | n>>(30-i)
if m > mx :
p = i
mx = m
print(mx)
return p
>>> largest(1217)
809500676
22
>>>
答案 2 :(得分:1)
这与FredOverflow的第二次尝试相同,虽然我添加了一组额外的括号,因为我总是忘记&
和|
优先级。
m = ((n << i) & 0x3fffffff) | (n >> (30-i));
给我1217测试(VS2010 SP1)的值为22