格雷码(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版的重要解析:


 


 

 

0 0
原创粉丝点击