1. 格雷码简介

格雷码跟8421码一样,也是一种对数字进行二进制编码的方法,只是编码方法跟常见的8421二进制编码方法不一样。

格雷码序列中,相邻的两个数字的二进制编码只有一位是不一样的,这种编码方式常用于较复杂的电路中。大家都知道二进制的 0/1 代表了电路的 开/关 ,例如n位的二进制编码,有很多情况下电路需要遍历 0 ~ 2^n 的情况,在电路实现中就是用n位的电路的开关依次转换来实现。

由于8421二进制编码的 0 ~ 2^n 的序列,相邻的两个数的二进制相差会出现多位不一样,因此电路在遍历时就需要同时变更多位电路开关,而这种操作是需要时间的,在这个过程中就有可能出现中间的状态,从而出现错误的编码。
例如:
n = 3 的 8421 编码

i 8421编码
0 000
1 001
2 010
3 011
4 100
5 101
6 110
7 111

相邻两个数之间的二进制编码相差的不止1位,就会出现上面说的情况。而格雷码编码中,相邻的两个数的二进制编码只有1位是不一样的,因此在物理电路的变换中只涉及到一位电路的开关操作,即操作是原子的,不会出现中间过程,也就不会出现错误编码了,因此在某些场景的电路信号中被广泛运用。

2. 格雷码与8421二进制码之间的转换

n = 3 为例,8421码与格雷码之间的对应关系如下:

格雷码也是以全0开头的

i 8421编码 格雷码
0 000 000
1 001 001
2 010 011
3 011 010
4 100 110
5 101 111
6 110 101
7 111 100

2.1 8421码 ==> 格雷码

算法
1、8421码最左边一位不变,保留下来成为格雷码的最左边一位;
2、从左边第二位开始,将8421码的每一位与它左边的一位相 异或 得到对应位的格雷码;

代码实现

public static int toGrayCode(int i) {return i ^ (i >> 1);
}

ii - 1 异或,也即将 i 的每一位与它的左边一位相异或。右移操作左边是补的0,0与任何数异或等于其本身,因此最左边一位被保留了。

2.2 格雷码 ==> 8421码

算法
1、格雷码的最左边一位保持不变,保留下来成为8421码的最左边一位;
2、从左边第二位开始,将格雷码的每一位与前一位计算得到的8421码 异或 得到当前的8421码;

解释

8421码转格雷码是通过 i ^ (i - 1) 实现的,要想将格雷码转换为8421码,我们知道,异或运算有如下性质:
(a ^ b) ^ b = a ^ (b ^ b) = a

因此,可以得到 (i ^ (i >> 1)) ^ (i >> 1) = i ^ ((i >> 1) ^ (i >> 1)) = i
所以在上面的算法中在计算当前位的8421码时,需要将当前位的格雷码与上一位计算得到的8421码异或。

代码实现

public static int toBinaryCode(int grayCode, int n) {String grayCodeStr = Integer.toBinaryString(grayCode);if (grayCodeStr.length() < n) {// 补齐0,使得二进制编码有n位int bitCnt = grayCodeStr.length();for (int i = bitCnt; i < n; i++) {grayCodeStr = "0" + grayCodeStr;}}StringBuilder binary = new StringBuilder();binary.append(grayCodeStr.charAt(0)); //最左边一位不变for (int i = 1; i < n; i++) {char cur = grayCodeStr.charAt(i);char preBinary = binary.charAt(i - 1);int tmp = (cur - '0') ^ (preBinary - '0');if (tmp == 0) binary.append('0');else binary.append('1');}return Integer.parseInt(binary.toString(), 2);
}

2.3 测试

public class Demo {public static void main(String[] args) {int n = 3;int powN = (int) Math.pow(2, n);int[] grayCode = new int[powN];System.out.println("========= Binary to GrayCode ==========");for (int i = 0; i < powN; i++) {grayCode[i] = toGrayCode(i);System.out.print(grayCode[i] + " ");}System.out.println();System.out.println("========= GrayCode to Binary ==========");for (int i = 0; i < powN; i++) {int binary = toBinaryCode(grayCode[i], n);System.out.print(binary + " ");}System.out.println();}public static int toGrayCode(int i) {return i ^ (i >> 1);}public static int toBinaryCode(int grayCode, int n) {String grayCodeStr = Integer.toBinaryString(grayCode);if (grayCodeStr.length() < n) {// 补齐0,使得二进制编码有n位int bitCnt = grayCodeStr.length();for (int i = bitCnt; i < n; i++) {grayCodeStr = "0" + grayCodeStr;}}StringBuilder binary = new StringBuilder();binary.append(grayCodeStr.charAt(0)); //最左边一位不变for (int i = 1; i < n; i++) {char cur = grayCodeStr.charAt(i);char preBinary = binary.charAt(i - 1);int tmp = (cur - '0') ^ (preBinary - '0');if (tmp == 0) binary.append('0');else binary.append('1');}return Integer.parseInt(binary.toString(), 2);}
}

可以看到二进制与格雷码之间是可以正确转换的。

参考文献

[1] https://baike.baidu.com/item/%E6%A0%BC%E9%9B%B7%E7%A0%81/6510858?fr=aladdin#5
[2] https://leetcode.com/problems/gray-code/

【算法】格雷码(Gray Code)与8421二进制码之间的转换算法 (LeetCode89)相关推荐

  1. gray code java_格雷码Gray Code详解

    格雷码简介 在一组数的编码中,若任意两个相邻的代码只有一位二进制数不同,则称这种编码为格雷码(Gray Code),另外由于最大数与最小数之间也仅一位数不同,即"首尾相连",因此又 ...

  2. 二进制格雷码与自然二进制码之间的转换

    什么是格雷码? 格雷码,又叫循环二进制码或反射二进制码,格雷码是我们在工程中常会遇到的一种编码方式,它的基本的特点就是任意两个相邻的代码只有一位二进制数不同. 二进制格雷码与自然二进制码的互换 1.二 ...

  3. 常用的几种在线地图(天地图、百度地图、高德地图)坐标系之间的转换算法

    1.首先弄明白几种在线地图的坐标系: (1)天地图:CGCS2000,2000国家大地坐标系:我们其实很多时候直接用WGS84的坐标来代替CGCS2000坐标.因为CGCS2000的定义与WGS84实 ...

  4. Java 算法 格雷码

    目录标题 题目描述 解题思路 代码 题目描述 格雷码是以n位的二进制来表示数. 与普通的二进制表示不同的是,它要求相邻两个数字只能有1个数位不同. 首尾两个数字也要求只有1位之差. 有很多算法来生成格 ...

  5. LeetCode(89):格雷编码 Gray Code(Java)

    2019.7.19 #程序员笔试必备# LeetCode 从零单刷个人笔记整理(持续更新) 智力题,本题的关键在于搞清楚格雷编码的生成过程, G(i) = i ^ (i/2). 如 n = 3: G( ...

  6. 火星坐标和百度坐标之间的转换算法

    在开始这个题目之前,先给大家再次扫扫盲,扫的不是坐标系统的盲,而是我们国家所使用的坐标系统.大家都知道,美国GPS使用的是WGS84的坐标系统,以经纬度的形式来表示地球平面上的某一个位置,这应该是国际 ...

  7. 计组——定点数原码反码补码移码以及它们之间的转换

    原码 用尾数表示真值的绝对值,符号位"0/1"对应"正/负" 若机器字长n+1位,原码整数的表示范围:−(2n−1)≤x≤2n−1{\color{Red} -( ...

  8. Gray Code(格雷码) C++多方法实现

    简介 在一组数的编码中,若任意两个相邻的代码只有一位二进制数不同,则称这种编码为格雷码(Gray Code),另外由于最大数与最小数之间也仅一位数不同,即"首尾相连",因此又称循环 ...

  9. 格雷码与普通二进制码的相互转换——学习笔记

    文章目录 格雷码 普通二进制码转换成格雷码 格雷码转换成普通二进制码 进一步 Reference 文章中内容与图片大部分来自Reference,本文只是以方便自己理解的方式进行整理. 格雷码 在一组数 ...

  10. 4位格雷码的顺序编码_格雷码那点事——递归非递归实现

    简介 在一组数的编码中,若任意两个相邻的代码只有一位二进制数不同,则称这种编码为格雷码(Gray Code),另外由于最大数与最小数之间也仅一位数不同,即"首尾相连",因此又称循环 ...

最新文章

  1. 5个常用Java代码混淆器 助你保护你的代码
  2. postgresql基本操作
  3. 远程连接linux(Ubuntu配置SSH服务)22端口
  4. QT的QAction类的使用
  5. RHCS创建高可用集群apche服务器
  6. python 文本文件处理_53 Python - txt普通文件处理
  7. html盒子居中的方式,CSS盒子居中三种方法
  8. 微软要放弃Edge了?传微软正在构建基于Chromium的浏览器
  9. java 封装log4j_Java项目 切片实现log4j的终极封装
  10. apt-cyg 代理设置
  11. FlashBuilder 4.6 破解序列号和方法
  12. 迅雷的php文件_使用迅雷下载.php文件的方法(Picjumbo可用)
  13. 用Python设计杂志订阅系统
  14. 自定义 QGraphicsItem
  15. macos安装盘第三方工具制作_如何制作macOS High Sierra USB启动安装盘
  16. 简单的MediaPlayer+SurfaceView实现视频横竖屏播放
  17. QUASI-HYPERBOLIC (拟双曲线) MOMENTUM AND ADAM FOR DEEP LEARNING——精读
  18. 超写实虚拟人制作教程
  19. 955 不加班公司名单:955.WLB
  20. Oracle Cloud(甲骨文)开启root登录

热门文章

  1. 幼儿园计算机游戏,幼儿园数学游戏大全(大中小班都有),不可错过!
  2. matlab版本下载地址
  3. Linux时间戳和标准时间的互转
  4. linux终端怎么复制粘贴某一行_超级小白帖:如何在Linux终端中复制粘贴
  5. 数据库实验一——数据定义
  6. Topic 19. 临床预测模型之输出每个患者列线图得分 (nomogramFormula)
  7. 手把手教你使用stata进行cox回归并制作列线图
  8. 【每天学一点新知识】getshell???webshell???
  9. C++和ASM文件的互相调用
  10. 编译报错:无法打开包括文件 No such file or directory