C 格雷码中的邻域

C 格雷码中的邻域,c,algorithm,gray-code,C,Algorithm,Gray Code,有什么算法可以用格雷码找到邻居吗 对于较小的数字,可以编写整个表格,但是如果我有一个像010 110这样的数字,那么用6个数字来编写整个格雷码表格就有点太多了。根据定义,任何带有单个位更改的扰动都是有效的相邻格雷码。问题在于,对于一个六位值,有六种可能的结果,并且在任何单个编码中,只有两种可能是正确的 随着字数的增加,非决定论变得更糟。无耻地抄袭自: 现在是请求的代码,使用掩码将位数限制为6: unsigned int nextGray(unsigned int num) { retur

有什么算法可以用格雷码找到邻居吗


对于较小的数字,可以编写整个表格,但是如果我有一个像010 110这样的数字,那么用6个数字来编写整个格雷码表格就有点太多了。

根据定义,任何带有单个位更改的扰动都是有效的相邻格雷码。问题在于,对于一个六位值,有六种可能的结果,并且在任何单个编码中,只有两种可能是正确的

随着字数的增加,非决定论变得更糟。

无耻地抄袭自:

现在是请求的代码,使用掩码将位数限制为6:

unsigned int nextGray(unsigned int num)
{
    return binaryToGray((grayToBinary(num) + 1) & 0x3F);
}

unsigned int prevGray(unsigned int num)
{
    return binaryToGray((grayToBinary(num) - 1) & 0x3F);
}

最快的解决方案是将格雷码转换为常规二进制,获取下一个值并将该值转换回格雷码。这些操作可能是最快和最简单的

否则,可以使用以下操作:

unsigned next_gray(unsigned gray)
{
    if (is_gray_odd(gray))
    {
        unsigned y = gray & -gray;
        return gray ^ (y << 1);
    }
    else
    {
        // Flip rightmost bit
        return gray ^ 1;
    }
}
功能
previous\u gray
将与功能
next\u gray
相同,只是您必须反转条件。无论如何,到常规的来回转换可能最终会更快

编辑:如果您使用的是GCC或Clang,您可以使用编译器内部的
\uuuuuu内置奇偶校验
来计算格雷码的奇偶校验(并可能检查是否存在
\uuuuuu GNUC\uuuuuuuuuu
\uuuuu Clang\uuuu
以保持跨平台):

如果这样做,在某些体系结构上,计算下一个/上一个格雷码可能比将格雷码来回转换为二进制更快。不管怎样,如果你想要速度,你最好选择基准

编辑2:如果您只需要两个邻居,而不关心前一个邻居和下一个邻居,那么您甚至不关心奇偶校验,您可以这样获得这两个邻居:

unsigned neighbour1 = gray ^ 1;
unsigned neighbour2 = gray ^ ((gray & -gray) << 1);
无符号邻域1=灰色^1;

unsigned neighbour2=gray^((gray&-gray)如果给定一个特定的n位格雷码值,您是否在询问如何获取下一个和上一个值?Wikipedia文章对此进行了讨论,并提供了一些参考。非常好。
bool is_gray_odd(unsigned gray)
{
    for (size_t i = CHAR_BIT * sizeof(int) / 2u ; i ; i >>= 1u)
    {
        gray ^= (gray >> i);
    }
    return (bool)(gray & 1u);
}
bool is_gray_odd(unsigned gray)
{
    return (bool) __builtin_parity(gray);
}
unsigned neighbour1 = gray ^ 1;
unsigned neighbour2 = gray ^ ((gray & -gray) << 1);