格雷码(Gray Code)的生成
来源:互联网 发布:nginx下载windows 编辑:程序博客网 时间:2024/05/17 18:48
1、什么是格雷码
Gray Code是一个数列集合,每个数使用二进制来表示,假设使用n位元来表示每个数字,那么任两个数之间只有一个位元值不同。
例如: 生成4位元的格雷码就是: 0000 0001 0011 0010 0110 0111 0101 0100 1100 1101 1111 1110 1010 1011 1001 1000
Gray Code的顺序并不是唯一的,可以是上面的所形成的数列的任意一种。Gray Code是由贝尔实验室的Frank Gray在1940年代提出的,用来在使用PCM(Pusle Code Modulation)方法传送讯号时避免出错,并于1953年三月十七日取得美国专利。如果要产生n位的格雷码,那么格雷码的个数为2^n个。
2、生成格雷码的原理
假设原始的值从0开始,格雷码产生的规律是:
第一步,改变最右边的位元值;
第二步,改变右边起第一个为1的位元的左边的位元;
第三步,第四步重复第一步和第二步,直到所有的格雷码产生完毕
举个例子来将:生成一个3位元的格雷码,假设原始值为 000
第一步: 改变最右边的位元值,则生成:001
第二步:改变右边起第一个为1的位元的左边的位元值,则生成011
第三步:改变最右边的位元值,则生成:010
第四步:改变右边起第一个为1的位元的左边的位元值,则生成110
第五步:改变最右边的位元值,则生成:111
第六步:改变右边起第一为1的位元的左边位元值:101
第七步:改变最右边的位元值,则生成:100
最后,3位元的格雷码全部生成。
按照这格雷码生成的规律,我们可以编写生成格雷码的代码(请看C语言版)
3、格雷码的实现
1、C语言实现格雷码(深度优先遍历)
#include <stdio.h>#include <malloc.h>void grayCode(char *a, int size, int index);void grayCode(char *a, int size, int index){if(index == size){//到达底部就输出printf("%s\n", a); }else{//深度优先遍历grayCode(a, size, index+1);if(a[index] == '0'){a[index] = '1';}else{//把当前为逆转a[index] = '0';}//继续向下搜索grayCode(a, size, index+1);}}void main(void){char * arr = NULL;int index = 0;arr = (char *)calloc(sizeof(char), 4);//先给字符串中没一位都赋值为'0';for(index = 0 ; index < 4; ++index){arr[index] = '0';}//生成格雷码grayCode(arr, 4, 0);}
看代码时,请看代码注释,会有对深度优先遍历解决生成格雷码有更进一步的理解。
2、Java实现格雷码(递归)
我们仔细观察一个3位元的格雷码:
000
001
011
010
110
111
101
100
仔细观察,如果除去最高位(最左边的第一位),格雷码中是上下对称的,所以我们完全可以使用递归的方法,在每一层的前面加上0或1,所以我们可以分析:
1、产生0、1两个字符串。
2、在第一步的基础上,每一个字符串都加上0 和1 ,所以就生成了00、01、10、11
3、在第二步的基础上,每一个字符串再加上0和1,所以就生成了000、001、010、011、100、101、110、111
所以3元的格雷码就生成了, 所以我们可以找到规律n位元格雷码是基于n-1位元格雷码产生的。
知道了这规律之后,就可以写出java的实现了:
public class GrayCode{public static String[] GrayCode(int n){// 生成 2^n个存储空间用于保存生成格雷码的种类String[] grayCode = new String[(int)Math.pow(2, n)];//如果是生成一位的格雷码,那么就是直接 返回 两种情况if(n ==1){grayCode[0] = "0";grayCode[1] = "1";return grayCode;}//求取n-1 位的格雷码String[] last = GrayCode(n-1);//拼接字符串,因为格雷码除去最高位为0或者为1 外,其余的都是对称的。所以 //后面的才有 grayCode[grayCode.length-1-i] = "1" + alst[i];for(int i = 0; i < last.length; ++i){grayCode[i] = "0" + last[i];grayCode[grayCode.length -1 -i] = "1" + last[i];}return grayCode;}public static void main(String[] args){String[] arr = GrayCode(4);for (int i = 0; i < arr.length; i++) {System.out.println(arr[i]);}}}
下面附上java版的重要解析:
- 格雷码(Gray Code)的生成
- 生成格雷码(Gray Code)
- LeetCode 89. Gray Code(生成格雷码)
- 递归——生成格雷码(gray code)
- Gray Code 简介及生成
- Gray code 的学习
- 递归生成格雷码 gray code generation using recursion(c++)
- [LeetCode] 格雷码(Gray Code)
- Gray Code 格雷码 @LeetCode
- Gray Code 格雷码编码
- leetcode Gray Code 格雷码
- Gray Code 格雷码
- 格雷码(gray code)
- LeetCode-Gray Code(格雷码)
- Gray Code 格雷码
- leetcode89-Gray Code(格雷码)
- [lintcode] Gray Code,格雷码
- 格雷码Gray Code
- whose view is not in the window hierarchy
- 杂记一
- Inorder Successor in BST
- 高仿- 萌聚 app。
- 谈Android模拟点击的价值和实现
- 格雷码(Gray Code)的生成
- java 集合之ArrayList集合元素重复删除
- hdu 1863 畅通工程 (最小生成树)
- 欢迎使用CSDN-markdown编辑器
- 基于Android实现保存图片到本地并可以在相册中显示出来
- JAVA学习笔记three:异常
- 产生任意数
- 【C语言】C语言概述
- lib and dll