Gray code(格雷码)【代码实现】

不羁岁月 提交于 2020-01-25 09:34:35

C

int gray_encode(int n) {
    return n ^ (n >> 1);
}
 
int gray_decode(int n) {
    int p = n;
    while (n >>= 1) p ^= n;
    return p;
}

示例:

#include <stdio.h>
 
/* Simple bool formatter, only good on range 0..31 */
void fmtbool(int n, char *buf) {
    char *b = buf + 5;
    *b=0;
    do {
	*--b = '0' + (n & 1);
	n >>= 1;
    } while (b != buf);
}
 
int main(int argc, char **argv) {
    int i,g,b;
    char bi[6],bg[6],bb[6];
 
    for (i=0 ; i<32 ; i++) {
	g = gray_encode(i);
	b = gray_decode(g);
	fmtbool(i,bi); fmtbool(g,bg); fmtbool(b,bb);
	printf("%2d : %5s => %5s => %5s : %2d\n", i, bi, bg, bb, b);
    }
    return 0;
}

输出:

0 : 00000 => 00000 => 00000 :  0
 1 : 00001 => 00001 => 00001 :  1
 2 : 00010 => 00011 => 00010 :  2
 3 : 00011 => 00010 => 00011 :  3
 4 : 00100 => 00110 => 00100 :  4
 5 : 00101 => 00111 => 00101 :  5
 6 : 00110 => 00101 => 00110 :  6
 7 : 00111 => 00100 => 00111 :  7
 8 : 01000 => 01100 => 01000 :  8
 9 : 01001 => 01101 => 01001 :  9
10 : 01010 => 01111 => 01010 : 10
11 : 01011 => 01110 => 01011 : 11
12 : 01100 => 01010 => 01100 : 12
13 : 01101 => 01011 => 01101 : 13
14 : 01110 => 01001 => 01110 : 14
15 : 01111 => 01000 => 01111 : 15
16 : 10000 => 11000 => 10000 : 16
17 : 10001 => 11001 => 10001 : 17
18 : 10010 => 11011 => 10010 : 18
19 : 10011 => 11010 => 10011 : 19
20 : 10100 => 11110 => 10100 : 20
21 : 10101 => 11111 => 10101 : 21
22 : 10110 => 11101 => 10110 : 22
23 : 10111 => 11100 => 10111 : 23
24 : 11000 => 10100 => 11000 : 24
25 : 11001 => 10101 => 11001 : 25
26 : 11010 => 10111 => 11010 : 26
27 : 11011 => 10110 => 11011 : 27
28 : 11100 => 10010 => 11100 : 28
29 : 11101 => 10011 => 11101 : 29
30 : 11110 => 10001 => 11110 : 30
31 : 11111 => 10000 => 11111 : 31

C++

#include <bitset>
#include <iostream>
#include <string>
#include <assert.h>
 
uint32_t gray_encode(uint32_t b)
{
    return b ^ (b >> 1);
}
 
uint32_t gray_decode(uint32_t g)
{
    for (uint32_t bit = 1U << 31; bit > 1; bit >>= 1)
    {
        if (g & bit) g ^= bit >> 1;
    }
    return g;
}
 
std::string to_binary(int value) // utility function
{
    const std::bitset<32> bs(value);
    const std::string str(bs.to_string());
    const size_t pos(str.find('1'));
    return pos == std::string::npos ? "0" : str.substr(pos);
}
 
int main()
{
    std::cout << "Number\tBinary\tGray\tDecoded\n";
    for (uint32_t n = 0; n < 32; ++n)
    {
        uint32_t g = gray_encode(n);
        assert(gray_decode(g) == n);
 
        std::cout << n << "\t" << to_binary(n) << "\t" << to_binary(g) << "\t" << g << "\n";
    }
}

输出:

Number	Binary	Gray	Decoded
0	0	0	0
1	1	1	1
2	10	11	3
3	11	10	2
4	100	110	6
5	101	111	7
6	110	101	5
7	111	100	4
8	1000	1100	12
9	1001	1101	13
10	1010	1111	15
11	1011	1110	14
12	1100	1010	10
13	1101	1011	11
14	1110	1001	9
15	1111	1000	8
16	10000	11000	24
17	10001	11001	25
18	10010	11011	27
19	10011	11010	26
20	10100	11110	30
21	10101	11111	31
22	10110	11101	29
23	10111	11100	28
24	11000	10100	20
25	11001	10101	21
26	11010	10111	23
27	11011	10110	22
28	11100	10010	18
29	11101	10011	19
30	11110	10001	17
31	11111	10000	16

C#

using System;
 
public class Gray {
    public static ulong grayEncode(ulong n) {
        return n^(n>>1);
    }
 
    public static ulong grayDecode(ulong n) {
        ulong i=1<<8*64-2; //long is 64-bit
        ulong p, b=p=n&i;
 
        while((i>>=1)>0)
            b|=p=n&i^p>>1;
        return b;
    }
 
    public static void Main(string[] args) {
        Console.WriteLine("Number\tBinary\tGray\tDecoded");
        for(ulong i=0;i<32;i++) {
            Console.WriteLine(string.Format("{0}\t{1}\t{2}\t{3}", i, Convert.ToString((long)i, 2), Convert.ToString((long)grayEncode(i), 2), grayDecode(grayEncode(i))));
        }
    }
}

Go

package main
 
import "fmt"
 
func enc(b int) int {
    return b ^ b>>1
}
 
func dec(g int) (b int) {
    for ; g != 0; g >>= 1 {
        b ^= g
    }
    return
}
 
func main() {
    fmt.Println("decimal  binary   gray    decoded")
    for b := 0; b < 32; b++ {
        g := enc(b)
        d := dec(g)
        fmt.Printf("  %2d     %05b   %05b   %05b  %2d\n", b, b, g, d, d)
    }
}

Java

public class Gray {
	public static long grayEncode(long n){
		return n ^ (n >>> 1);
	}
 
	public static long grayDecode(long n) {
		long p = n;
		while ((n >>>= 1) != 0)
			p ^= n;
		return p;
	}
	public static void main(String[] args){
		System.out.println("i\tBinary\tGray\tDecoded");
		for(int i = -1; i < 32;i++){
			System.out.print(i +"\t");
			System.out.print(Integer.toBinaryString(i) + "\t");
			System.out.print(Long.toBinaryString(grayEncode(i))+ "\t");
			System.out.println(grayDecode(grayEncode(i)));
		}
	}
}

Kotlin

// version 1.0.6
 
object Gray {
    fun encode(n: Int) = n xor (n shr 1)
 
    fun decode(n: Int): Int {
        var p  = n
        var nn = n
        while (nn != 0) {
            nn = nn shr 1
            p = p xor nn
        }
        return p
    }
}
 
fun main(args: Array<String>) {
    println("Number\tBinary\tGray\tDecoded")
    for (i in 0..31) {
        print("$i\t${Integer.toBinaryString(i)}\t")
        val g = Gray.encode(i)
        println("${Integer.toBinaryString(g)}\t${Gray.decode(g)}")
    }
}

PHP

<?php
 
/**
 * @author Elad Yosifon
 */
 
/**
 * @param int $binary
 * @return int
 */
function gray_encode($binary){
	return $binary ^ ($binary >> 1);
}
 
/**
 * @param int $gray
 * @return int
 */
function gray_decode($gray){
	$binary = $gray;
	while($gray >>= 1) $binary ^= $gray;
	return $binary;
}
 
for($i=0;$i<32;$i++){
	$gray_encoded = gray_encode($i);
	printf("%2d : %05b => %05b => %05b : %2d \n",$i, $i, $gray_encoded, $gray_encoded, gray_decode($gray_encoded));
}

Python

int<>bin转换

>>> def int2bin(n):
	'From positive integer to list of binary bits, msb at index 0'
	if n:
		bits = []
		while n:
			n,remainder = divmod(n, 2)
			bits.insert(0, remainder)
		return bits
	else: return [0]
 
 
>>> def bin2int(bits):
	'From binary bits, msb at index 0 to integer'
	i = 0
	for bit in bits:
		i = i * 2 + bit
	return i

bin<>gray转化:

>>> def bin2gray(bits):
	return bits[:1] + [i ^ ishift for i, ishift in zip(bits[:-1], bits[1:])]
 
>>> def gray2bin(bits):
	b = [bits[0]]
	for nextb in bits[1:]: b.append(b[-1] ^ nextb)
	return b

Ruby

class Integer
  # Converts a normal integer to a Gray code.
  def to_gray
    raise Math::DomainError, "integer is negative" if self < 0
    self ^ (self >> 1)
  end
 
  # Converts a Gray code to a normal integer.
  def from_gray
    raise Math::DomainError, "integer is negative" if self < 0
    recurse = proc do |i|
      next 0 if i == 0
      o = recurse[i >> 1] << 1
      o | (i[0] ^ o[1])
    end
    recurse[self]
  end
end
 
(0..31).each do |number|
  encoded = number.to_gray
  decoded = encoded.from_gray
  printf "%2d : %5b => %5b => %5b : %2d\n",
         number, number, encoded, decoded, decoded
end
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!