BITWISE和(&)数字范围

时间:2015-08-11 18:38:37

标签: bit-manipulation bitwise-operators bitwise-and

给出两个数字L& R,找到位于L和R之间的所有数字的按位和

约束1<= L,R <= (2^32)

LL step = 1;
    while(L!=R)
    {
        L/=2; R/=2; step*=2;
    }
    cout<<L*step<<endl;

有人可以帮我解释上述代码背后的解释或逻辑吗?

3 个答案:

答案 0 :(得分:5)

是的,它有点难,需要在纸上画草图。一旦你明白这个想法就很简单了。我将从简单的例子开始用英语解释。最重要的是让我们放心,因为我们对两个数字有点想法,并考虑两者之间的数字。

首先,让我们说一些规则: 1)如果两个数字相等,则它们之间不会有数字。 2)如果两个数字不相等,则它们之间的连续数字将在每个数字处包含ZERO,因此它们的按位AND将为零。

在进入示例之前,我们应该解释上面的简单算法。

1)每个除以2表示从数字右侧删除二进制数字。 (这是如何用二进制除以两种方式)。 2)每次分割时,我们将步长变量加倍。简单来说,步变量更像是一个计数器,它在两个数字相等之前保持最高位数值。

假设我们有以下示例:

L:11110001 R:11110011

S = 1(二进制00000001)

将算法应用于这些值:

由于L和R不相等,从每个中断一个二进制数字(每个除以2)并将S乘以2; 在第一轮他们成为

L:1111000 R:1111001

S = 2(二进制00000010)

由于它们不相等,请再次执行,结果是:

L:111100 R:111100

现在它们是相同的,循环中断和结果

是左数(或右数,因为它们相等)* S值。

当我们在Binary中加倍时,我们在右边添加一个零。这里我们需要3个零,因为S是00000010

11110000这是预期的。

结论:通过分割来保持切碎,直到两者相等并且它们之间没有任何东西。当你这样做时,不断更新你所处的步骤:)

答案 1 :(得分:1)

首先让我们考虑对两个数字进行按位和做什么,例如(0b表示基数为2)

4 & 7 = 0b100 & 0b111 = 0b100
5 & 7 = 0b101 & 0b111 = 0b101
5 & 6 = 0b101 & 0b110 = 0b100

运营商&amp;保留那些在两个数字中设置的位。

对于几个号码,运营商&amp;保留每个数字为1的那些位。

换句话说,任何数字中的位为0都会在答案的相应位中产生0。

现在考虑一个范围

[m = 0bxyz0acd,n = 0bxyz1rst] 这里xyzpacdrst都是基数为2的数字。

我们可以找到两个在[m,n]

范围内特殊的数字

(1)m&#39; = 0bxyz0111 (2)n&#39; = 0bxyz1000 范围[m,n]中所有数字的按位AND只是两个特殊数字的按位AND

rangeBitwiseAnd(m,n)= m&#39; &安培; ñ&#39; = 0bxyz0000 这告诉我们,按位和范围是从左到右保持m和n的公共位,直到它们不同的第一位,其余为填充零。

答案 2 :(得分:0)

当我们在结果答案中对数字范围进行“&”运算时,如果某位为0,则意味着该位一次为0。 因此我们可以将每个位右移,直到两个值都不相同。当两个值相同时,则将不同的位总数左移。代码为

    class Solution {
        public int rangeBitwiseAnd(int m, int n) {

            // if m !==n that means one of the bits is 0 so keep right shifting 
           //untill all the bits in both are same  and when they are same number of 
           //shift will be equal to number of bits not same just right shift it then

            int s = 0;
            while(m !=n){
                m =  m>>1;
                n = n>>1;

                s++;
            }
             return (m<<s);
        }
    }