我在各种论坛上搜索,但没有得到正确的答案。如果您能提供解决方案,那将非常好。
我的解决方法是 - 将两个整数转换为二进制,并分别添加两个数字中的数字,然后找到两个数字中数字总和之间的差异。如果差为一,则它们是格雷码邻居。
但我觉得这种方法并不适用于所有情况。非常感谢您的帮助。提前致谢!
实际上,其他一些答案似乎是错误的:两个二进制反射格雷码邻居仅相差一位(我假设您所说的“the”格雷码序列指的是由弗兰克·格雷描述的原始二进制反射格雷码序列)。但是,这并不意味着相差一位的两个格雷码是邻居(a => b并不意味着b => a)。例如,格雷码1000和1010仅相差一位,但它们不是邻居(在十进制中,分别为15和12)。
如果您想知道两个格雷码a和b是否是邻居,您必须检查previous(a)=b或next(a)=b。对于给定的格雷码,通过翻转最右边的位可以得到一个邻居,通过翻转右侧最右侧集合位的左侧位可以得到另一个邻居。对于格雷码1010,邻居是1011和1110(1000不是它们之一)。
通过翻转这些位之一来获取先前或下一个邻居实际上取决于格雷码的奇偶性。但是,由于我们需要两个邻居,因此我们不必检查奇偶性。以下伪代码应告诉您两个格雷码是否为邻居(使用类似于C的位运算):
function are_gray_neighbours(a: gray, b: gray) -> boolean
return b = a ^ 1 OR
b = a ^ ((a & -a) << 1)
end
上面的位操作技巧: a & -a
可以隔离一个数字中最右边的那个置位位。我们将该位向左移动一位即可得到需要翻转的位。
#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
一些测试用例:
参考文献: 上方使用的gTob()方法来自rodrigo在这篇文章中The neighbors in Gray code
public int checkConsecutive2(int b1, int b2){
int x = (b1 ^ b2);
if((x & (x - 1)) !=0){
return 0;
}else{
return 1;
}
}
public boolean grayCheck(int x, int y) {
int z = x^y;
return (z&z-1)==0;
}
一个显而易见的答案,但它是有效的。 将每个格雷码转换为其相应的二进制形式,然后相减。如果你的答案是+1或-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;
}
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));
}
}
a=int(input())
b=int(input())
x=a^b
if((x and (not(x & (x - 1))) )):
print("True")
else:
print("False")
我也曾在面试中遇到过这个问题。判断两个值是否是格雷码序列的条件之一是它们的值只相差一位。以下是解决此问题的方案:
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
a => b
不代表 b => a
)。 - Morwenn