Как узнать, являются ли два числа последовательными числами в последовательности кода Грея

Я пытаюсь найти решение проблемы, заключающейся в том, что для двух чисел нужно определить, являются ли они последовательными числами в последовательности кода Грея, то есть являются ли они соседями по коду Грея, предполагая, что последовательность кода Грея не упоминается.

Я искал на различных форумах, но не мог найти правильный ответ. Было бы здорово, если бы вы могли предоставить решение для этого.

Моя попытка решить проблему - преобразовать два целых числа в двоичные и добавить цифры в оба числа по отдельности и найти разницу между суммой цифр в двух числах. Если разница составляет единицу, то они являются соседями по коду Грея.

Но я чувствую, что это не сработает для всех случаев. Любая помощь высоко ценится. Заранее большое спасибо!!!


person user3923643    schedule 30.11.2014    source источник
comment
a и b являются соседями по коду Грея, если они отличаются только одним битом, то есть если XOR b является степенью числа 2.   -  person Peter de Rivaz    schedule 01.12.2014
comment
Обратите внимание, что здесь много последовательностей кода Грея. Вы имеете в виду конкретную последовательность или хотите знать, могут ли два числа быть соседями в некоторой последовательности кода Грея?   -  person ErikR    schedule 01.12.2014
comment
Большое спасибо за ваши ответы. Можно ли узнать, являются ли данные два числа соседями по коду Грея в некоторой последовательности? Последовательность в вопросе не указана. Я наткнулась в одном из интервью. Любая помощь приветствуется!!!   -  person user3923643    schedule 01.12.2014


Ответы (9)


Мне тоже пришлось решать этот вопрос в интервью. Одним из условий для того, чтобы два значения были последовательностью кода Грея, является то, что их значения отличаются только на 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
person David.Jones    schedule 30.11.2014
comment
Этот ответ неверен. См. Морвенн. ответ. - person Craig McQueen; 20.03.2015
comment
@DavidJones « [...] это правда, что два соседа по коду Грея отличаются только одним битом. Однако это не означает, что два кода Грея, отличающиеся одним битом, являются соседними (a => b не означает, что b => a). » - person Morwenn; 20.03.2015

На самом деле, несколько других ответов кажутся неверными: это правда, что два соседа двоичного отраженного кода Грея отличаются только одним битом (я предполагаю, что под «этой» последовательностью кода Грея вы подразумеваете исходный двоичный отраженный код Грея). кодовая последовательность, описанная Фрэнком Греем). Однако это не означает, что два кода Грея, отличающиеся одним битом, являются соседними (a => b не означает, что b => a). Например, коды Грея 1000 и 1010 отличаются только одним битом, но не являются соседями (1000 и 1010 соответственно равны 15 и 12 в десятичном виде).

Если вы хотите узнать, являются ли два кода Грея a и b соседними, вы должны проверить, являются ли previous(a) = b OR 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 изолирует самый правый установленный бит в числе. Мы сдвигаем этот бит на одну позицию влево, чтобы получить бит, который нам нужно перевернуть.

person Morwenn    schedule 06.12.2014
comment
Потрясающее решение. Это лучший из всех и правильный тоже. Хорошая работа, чувак. - person Sameer Sawla; 15.12.2014
comment
На основе принятого ответа на math.stackexchange.com/questions/965168/ , ваш псевдокод не может пройти через все возможности соседей. Пример двух последовательностей кода Грея одинаковой длины: [000,001,011,010,110,111,101,100], [000,001,011,111,101,100,110,010]. Код 000 может иметь более двух законных соседей. - person Di Wu; 22.10.2015
comment
@DiWu Конечно, мой ответ предполагает двоичную отраженную последовательность кода Грея, о которой обычно говорят, когда ничего не указано. - person Morwenn; 22.10.2015

Предположения: Входные данные 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) --> True (поскольку (1001, 1011) отличаются только одним битом и являются последовательными числами в десятичном представлении)
  • areGrayNeighbors(9,10) --> False
  • areGrayNeighbors(14,10) --> Истина

Ссылки: использованный выше метод gTob() принадлежит Родриго в этом сообщении соседи по коду Грея

person codeKaichu    schedule 27.12.2014

Если два числа находятся в последовательности кода Грея, они отличаются на одну двоичную цифру. то есть исключающее ИЛИ для двух чисел возвращает степень 2. Итак, найдите XOR и проверьте, является ли результат степенью двойки.

Это решение хорошо работает для всех тестов, написанных CodeKaichu выше. Я хотел бы знать, если это терпит неудачу в каких-либо случаях.

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

Очевидный ответ, но он работает. Преобразуйте каждый код Грея в соответствующую ему двоичную форму, вычтите два. Если ваш ответ является двоичным эквивалентом +1 или -1, то два кода Грея являются соседними.

Это кажется излишеством, но когда вы сидите на собеседовании и не знаете правильного метода, это работает. Кроме того, для оптимизации можно проверить фильтр разности отдельных битов, чтобы не тратить время на преобразование и вычитание чисел, которые, как мы точно знаем, не являются соседними.

person leo    schedule 07.09.2015

Если вы просто хотите проверить, отличаются ли входные числа всего на один бит:

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;
}
person codeKaichu    schedule 27.12.2014

Вы можете проверить, отличаются ли два числа на один бит или нет, следующим образом. В этом методе учитывается разница в длине двоичных чисел. Например, вывод для 11 (1011) и 3 (11) будет возвращен как истина. Кроме того, это не решает второй критерий смежности кода Грея. Но если вы хотите проверить, отличаются ли числа только на один бит, код ниже поможет.

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));
    }
}
person Aswin    schedule 02.03.2015
comment
За что голосование против? Я ясно упомянул, что этот метод проверяет только первые критерии. Во время собеседований в технических компаниях меня попросили написать код для этой конкретной задачи, и их не интересовал точный тест смежности кода Грея. - person Aswin; 17.04.2015

Если два числа находятся в последовательности кода Грея, они отличаются на одну двоичную цифру. то есть исключающее ИЛИ для двух чисел возвращает степень 2. Итак, найдите XOR и проверьте, является ли результат степенью двойки.

питон 3.8

a=int(input())
b=int(input())
x=a^b 
if((x and (not(x & (x - 1))) )):
    print("True")
else:
    print("False")
person kabali    schedule 21.11.2020
comment
Похоже, это не отличается от ошибочного принятого ответа Дэвида Джонса. - person greybeard; 21.11.2020

person    schedule
comment
Пожалуйста, добавьте небольшое объяснение, почему вы думаете, что это отвечает на вопрос ОП. - person iRuth; 26.03.2015
comment
Вы пытались прочитать и понять принятый ответ и ответ Морвенн, и почему они оцениваются по-разному? - person greybeard; 26.03.2015