TDD (练习) Gray Code 格雷码和二进制 Binary 互转

题目

Create functions to encode a number to and decode
a number from Gray code. Display the normal binary
representations, Gray code representations, and
decoded Gray code values for all 5-bit binary
numbers (0-31 inclusive, leading 0's not necessary).

There are many possible Gray codes. The following
encodes what is called "binary reflected Gray code."

Encoding (MSB is bit 0, b is binary, g is Gray code):
if b[i-1] = 1
g[i] = not b[i]
else
g[i] = b[i]

Decoding (MSB is bit 0, b is binary, g is Gray code):
b[0] = g[0]

for other bits:
b[i] = g[i] xor b[i-1]

背景

典型的二进制格雷码(Binary Gray Code)简称格雷码,因1953年公开的弗兰克·格雷(Frank Gray,18870913-19690523)专利“Pulse Code Communication”而得名,当初是为了通信,现在则常用于模拟-数字转换和位置-数字转换中。法国电讯工程师波特(Jean-Maurice-Émile Baudot,18450911-19030328)在1880年曾用过的波特码相当于它的一种变形。1941年George Stibitz设计的一种8元二进制机械计数器正好符合格雷码计数器的计数规律。

二进制码→格雷码 说明

此方法从对应的n位二进制码字中直接得到n位格雷码码字,步骤如下:

  1. 对n位二进制的码字,从右到左,以0到n-1编号

  2. 如果二进制码字的第i位和i+1位相同,则对应的格雷码的第i位为0,否则为1(当i+1=n时,二进制码字的第n位被认为是0,即第n-1位不变) [4]

公式表示

image
(G:格雷码,B:二进制码)

关注点:

  • 顺序是右到左,和我们通常使用的序号是反的。
  • 第n-1位不变,比如 011 0是第n-1位,第n位认为是0,相当于在前面加了0变成 0011,0和 0 or 1 异或不会改变原来的值。
    输入 - B : 011 转换 过程 1^1 =1 1^0=0 0^0=0(第n-1位不变) 输出 G : 010

格雷码→二进制码 说明

从左边第二位起,将每位与左边一位解码后的值异或,作为该位解码后的值(最左边一位依然不变)。依次异或,直到最低位。依次异或转换后的值(二进制数)就是格雷码转换后二进制码的值。

公式表示

image

(G:格雷码,B:二进制码)

关注点

  • 顺序不变, n-1不变。b[n-1] 异或 g[n-2] = b[n-2] 以此类推到第0位。
  • 输入G: 111 b[n-1] = g[n-1] b[n-2] = b[n-1] 异或 g[n-2] 输出 B: 101

测试代码

public class GrayCodeTest {

    @Test
    public void should_001_encode_001(){
        String input="001";
        String except ="001";
        String result = GrayCode.encode(input);
        assertEquals(except,result);
    }

    @Test
    public void should_010_encode_011(){
        String input="010";
        String except ="011";
        String result = GrayCode.encode(input);
        assertEquals(except,result);
    }
    @Test
    public void should_0111_encode_0100(){
        String input="0111";
        String except ="0100";
        String result = GrayCode.encode(input);
        assertEquals(except,result);
    }

    @Test
    public void should_0100_decode_0111(){
        String input="0100";
        String except ="0111";
        String result = GrayCode.decode(input);
        assertEquals(except,result);
    }
    @Test
    public void should_100_decode_111(){
        String input="100";
        String except ="111";
        String result = GrayCode.decode(input);
        assertEquals(except,result);
    }
    @Test
    public void should_001_decode_001(){
        String input="001";
        String except ="001";
        String result = GrayCode.decode(input);
        assertEquals(except,result);
    }

}

实现代码

public class GrayCode {

    public static String encode(String input) {
        int len = input.length();
        String[] result = new String[len];

        for (int i = len-1; i>0 ; i--) {
            result[i]=String.valueOf(input.charAt(i)^input.charAt(i-1));
        }
        result[0]=String.valueOf(input.charAt(0));
        return String.join("",result);
    }

    public static String decode(String input) {

        int len = input.length();
        String[] result = new String[len];

        for (int i = 0; i<=len-1 ; i++) {
            if(i==0){
                result[i] = String.valueOf(input.charAt(0));
            }else {
                result[i] = String.valueOf(result[i-1].charAt(0)^input.charAt(i));
            }
        }
        return String.join("",result);

    }
}

Gray Code 理解如何转码编码需要花些时间,实现代码并不复杂。写代码就是需要理解问题,通常需要手工实现然后代码实现。

参考
格雷码(Gray)和二进制(Binary)之间的相互转换
百度百科-格雷码

你可能感兴趣的:(TDD (练习) Gray Code 格雷码和二进制 Binary 互转)