如何查找两个数字是否为格雷码序列中的连续数字

时间:2014-11-30 22:14:12

标签: java python c algorithm gray-code

我试图找到给出两个数字的问题的解决方案,找出它们是否是格雷码序列中的连续数字,即,如果它们是灰色代码邻居,则假设未提及格雷码序列。

我在各种论坛上搜索但无法得到正确的答案。如果你能为此提供解决方案,那就太好了。

我对此问题的尝试 - 将两个整数转换为二进制并分别在两个数字中添加数字,并找出两个数字中数字之和的差异。如果差异是1,则它们是格雷码邻居。

但我觉得这不适用于所有情况。任何帮助都非常感谢。非常感谢提前!!!

9 个答案:

答案 0 :(得分:28)

实际上,其他几个答案似乎都是错误的:两个二元反射格雷码邻居确实只有一位相差(我假设通过«格雷码序列,你的意思是原始的二元反射格雷码序列,如Frank Gray所述。但是,这并不意味着相差一位的两个格雷码是邻居(a => b并不意味着b => a)。例如,格雷码1000和1010只相差一位但不是邻居(1000和1010分别是十进制的15和12)。

如果您想知道两个格雷码ab是否是邻居,则必须检查previous(a) = b OR next(a) = b是否为function are_gray_neighbours(a: gray, b: gray) -> boolean return b = a ^ 1 OR b = a ^ ((a & -a) << 1) end 。对于给定的格雷码,通过翻转最右边设置位左侧的位,可以通过翻转最右边的位和另一个邻居位来获得一个邻居。对于格雷码1010,邻居是1011和1110(1000不是其中之一)。

通过翻转其中一个位来获得前一个或下一个邻居实际上取决于格雷码的奇偶校验。但是,由于我们想要两个邻居,我们不必检查奇偶校验。以下伪代码应该告诉您两个格雷码是否是邻居(使用类似C的按位运算):

a & -a

上面的位技巧:{{1}}隔离了数字中最严格的设置位。我们将该位向左移动一个位置以获得我们需要翻转的位。

答案 1 :(得分:1)

假设: 输入a和b是二进制反射格雷码中的格雷码序列。 即a和b的位编码是二进制格雷码表示。

#convert from greycode bits into regular binary bits
def gTob(num): #num is binary graycode 
    mask = num >> 1
    while mask!=0:
        num = num^mask
        mask >>= 1
    return num; #num is converted 

#check if a and b are consecutive gray code encodings
def areGrayNeighbors(a,b):
    return abs(gTob(a) - gTob(b)) == 1

几个测试用例:

  • areGrayNeighbors(9,11) - &gt; True (因为(1001,1011)只有一个不同 位和十进制表示的连续数字)
  • areGrayNeighbors(9,10) - &gt;错误
  • areGrayNeighbors(14,10) - &gt;真

<强>参考文献:      上面使用的方法gTob()来自本文[{3}}

中的rodrigo

答案 2 :(得分:0)

public int checkConsecutive2(int b1, int b2){
    int x =  (b1 ^ b2);

    if((x & (x - 1)) !=0){
      return 0;
    }else{
      return 1;
    }

}

答案 3 :(得分:0)

如果两个数字是格雷码序列,则它们相差一个二进制数字。即两个数字上的异或返回2的幂。因此,找到XOR并检查结果是否为2的幂。

此解决方案适用于上面CodeKaichu编写的所有测试用例。我想知道它是否在任何情况下都失败了。

public boolean grayCheck(int x, int y) {
       int z = x^y;
       return (z&z-1)==0;
}

答案 4 :(得分:0)

一个明显的答案,但它确实有效。 将每个格雷码转换为各自的二进制格式,减去这两个格式。如果你回答的是二进制等效值+1或-1,则两个灰色代码相邻。

这似乎是一种过度杀戮,但是当你在面试中选址并且不知道正确的方法时,这是有效的。同样为了优化,可以检查单比特差分滤波器,因此我们不会浪费时间转换和减去我们知道肯定不相邻的数字。

答案 5 :(得分:-1)

如果您只想检查输入数字是否只有一位:

public boolean checkIfDifferByOneBit(int a, int b){
    int diff = 0;
    while(a > 0 && b > 0){
        if(a & 1 != b & 1)
            diff++;
        a = a >> 1;
        b = b >> 1;
    }
    if (a > 0 || b > 0) // a correction in the solution provided by David Jones
        return diff == 0 // In the case when a or b become zero before the other
    return diff == 1;
}

答案 6 :(得分:-1)

您可以检查两个数字是否相差一位,如下所示。在该方法中,考虑了二进制数长度的差异。例如,11(1011)和3(11)的输出将返回true。 此外,这不能解决格雷码邻接的第二个标准。但如果您只想检查数字是否相差一位,则下面的代码会有所帮助。

class Graycode{
    public static boolean graycheck(int one, int two){
        int differences = 0;
        while (one > 0 || two > 0){
            // Checking if the rightmost bit is same
            if ((one & 1) != (two & 1)){
                differences++;
            }
            one >>= 1;
            two >>= 1;
        }
        return differences == 1;
    }
    public static void main(String[] args){
        int one = Integer.parseInt(args[0]);
        int two = Integer.parseInt(args[1]);
        System.out.println(graycheck(one,two));
    }
}

答案 7 :(得分:-1)

如果两个数字在格雷码序列中,则它们相差一个二进制数字。也就是说,两个数字的异或将返回2的幂。因此,找到XOR并检查结果是否为2的幂。

python 3.8

a=int(input())
b=int(input())
x=a^b 
if((x and (not(x & (x - 1))) )):
    print("True")
else:
    print("False")

答案 8 :(得分:-7)

我也必须在面试中解决这个问题。两个值为格雷码序列的条件之一是它们的值仅相差1位。以下是此问题的解决方案:

def isGrayCode(num1, num2):
    differences = 0
    while (num1 > 0 or num2 > 0):
        if ((num1 & 1) != (num2 & 1)):
            differences++
        num1 >>= 1
        num2 >>= 1
    return differences == 1