【问题标题】:Calculate number of bit shifting in 30 bit integers that gives a maximum value计算给出最大值的 30 位整数的位移位数
【发布时间】:2011-07-19 03:22:32
【问题描述】:

我正在准备一次编程面试。所以,我试图解决一些过时的面试问题,为即将到来的面试做好准备。我一直在解决以下问题:

30 位无符号整数 X 的循环右移是通过将 X 的二进制表示的所有位右移一个位置并将最高有效位移动到最低有效位而获得的数字。准确地说,如果 X 的二进制表示是

X29 X28 ... X2 X1 X0

X的右循环移位的二进制表示是

X28 ... X2 X1 X0 X29

例如,给定数字 X(为便于阅读添加了数字内空格):

00 0000 0000 0000 0000 0100 1100 0001BIN = 1217DEC

它的右循环移位是

00 0000 0000 0000 0000 1001 1000 0010BIN = 2434DEC。

循环移位操作可以重复进行,例如给定相同的X值,其右循环移位3为:

00 0000 0000 0000 0010 0110 0000 1000BIN = 9736DEC

写一个函数

int maximum_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 位

解决此问题的最佳方法是什么?我确信解决方案很简单,它只需要一些关于位移的知识。

谢谢

【问题讨论】:

  • 你的面试官似乎不知道左移和右移之间的区别。
  • 同意@BenVoigt。而是左循环移位。

标签: c++ bit bit-shift


【解决方案1】:

解决这个问题的最佳方法是什么?

m = (n << i) & 0x3fffffff;

【讨论】:

  • 感谢您的快速回复。你能解释一下这背后的逻辑是什么吗?您如何确定要“与”该值的十六进制数?
  • @Bob: 0x3fffffff 是两个零,后跟 30 个 ;)
  • @Bob:你的班次还不是循环的。 m = (n &lt;&lt; i) &amp; 0x3fffffff | (n &gt;&gt; (30-i)) 怎么样?
  • 不,它仍然没有给出正确的输出。使用比特不好玩吧?
【解决方案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
>>> 

【讨论】:

    【解决方案3】:

    这与 FredOverflow 的第二次尝试相同,尽管我确实添加了一组额外的括号,因为我总是忘记 &amp;| 的优先级。

    m = ((n << i) & 0x3fffffff) | (n >> (30-i));
    

    1217 测试 (VS2010 SP1) 的值为 22

    【讨论】:

      猜你喜欢
      • 2016-03-11
      • 1970-01-01
      • 2021-11-10
      • 1970-01-01
      • 2020-04-13
      • 1970-01-01
      • 2017-03-29
      • 2015-06-30
      相关资源
      最近更新 更多