生成格雷码

算法设计与分析老师又出了个练习题:

 

利用分治策略设计一个算法,对任意的n构造相应的“格雷码”。“格雷码”(Gray code)是一个长度为2n的序列,满足

 

A) 每个元素都是长度为n比特的串。

 

B) 序列中无相同元素。

 

C) 连续的两个元素恰好只有1比特的不同。

 

例如,n=2时,格雷码为{00011110}。

    二进制格雷码(也被称为二进制循环码)是一种无权码,其特点是任何相邻的两个码字中仅有一位代码不同,其他代码是一样的,所以二进制格雷码又叫单位距离码。仔细观察格雷码的编码方式:如果按顺序将格雷码每四个分为一组,对于格雷码的最后一位,具有折叠反射特性,即:最后一位的顺序为 01 10,01 10,.....如果按顺序将格雷码每8个分为一组,则其倒数第2为的顺序为0011,1100,0011,1100.....同样,倒数第3为的顺序为0001111,1111000.这种特性称为反射特性。
格雷码是一种具有反射特性和循环特性的单步自补码,其循环和单步特性消除了随机取数时出现重大错误的可能,其反射和自补特性使得对其进行求反操作也非常方便,所以,格雷码属于一种可靠性编码,是一种错误最小化的编码方式,因此格雷码在通信和测量技术中得到广泛应用。

网上找了一下没看到用分治法的!

我自己写了个算法,我写出了n=1,2,3,4的所有格雷码,我发现了个规律:n每加1,那么就是将n-1的格雷码每一个都在后面添1和0,但次序变下(就是先加1和0,后面就加0和1)就是反射特性!

GrayCode
 1 /*
2 * To change this template, choose Tools | Templates
3 * and open the template in the editor.
4 */
5
6 /**
7 *
8 * @author Administrator
9 */
10 import java.util.*;
11
12 public class GrayCode {
13
14 public static int flag = 2;
15
16 public static void main(String[] args) {
17 int t, n;
18 System.out.print("n=");
19 Scanner reder = new Scanner(System.in);
20 t = reder.nextInt();
21 n = (int) Math.pow(2, (double) t);
22 int[][] gray = new int[n][t];
23 System.out.println("The GrayCode is: ");
24 if (t == 1) {
25 System.out.println("0");
26 System.out.println("1");
27 } else {
28 gray[n / 2 - 2][0] = 0;
29 gray[n / 2 - 2][1] = 0;
30 gray[n / 2 - 1][0] = 0;
31 gray[n / 2 - 1][1] = 1;
32 gray[n / 2][0] = 1;
33 gray[n / 2][1] = 1;
34 gray[n / 2 + 1][0] = 1;
35 gray[n / 2 + 1][1] = 0;
36 if (t > 2) {
37 com(gray, n / 2 - 2, n / 2 + 1);
38 }
39
40 for (int i = 0; i < gray.length; i++) {
41 for (int j = 0; j < gray[i].length; j++) {
42 System.out.print(gray[i][j] + " ");
43
44 }
45 System.out.println("");
46 }
47 }
48 }
49
50 public static void com(int[][] gray, int up, int down) {
51 int fUp = gray.length / 2 - (int) Math.pow(2, (double) flag);
52 int fDown = gray.length / 2 + (int) Math.pow(2, (double) flag) - 1;
53 int t = 0;
54 for (int i = up; i < gray.length / 2; i++) {
55 System.arraycopy(gray[i], 0, gray[fUp + t], 0, gray[i].length);
56 gray[fUp + (t++)][flag] = 0;
57
58 System.arraycopy(gray[i], 0, gray[fUp + t], 0, gray[i].length);
59 gray[fUp + (t++)][flag] = 1;
60 i++;
61 System.arraycopy(gray[i], 0, gray[fUp + t], 0, gray[i].length);
62 gray[fUp + (t++)][flag] = 1;
63
64 System.arraycopy(gray[i], 0, gray[fUp + t], 0, gray[i].length);
65 gray[fUp + (t++)][flag] = 0;
66 }
67 t = 0;
68 for (int i = down; i > gray.length / 2; i--) {
69
70 System.arraycopy(gray[i], 0, gray[fDown - t], 0, gray[i].length);
71 gray[fDown - (t++)][flag] = 0;
72
73 System.arraycopy(gray[i], 0, gray[fDown - t], 0, gray[i].length);
74 gray[fDown - (t++)][flag] = 1;
75 i--;
76 System.arraycopy(gray[i], 0, gray[fDown - t], 0, gray[i].length);
77 gray[fDown - (t++)][flag] = 1;
78
79 System.arraycopy(gray[i], 0, gray[fDown - t], 0, gray[i].length);
80 gray[fDown - (t++)][flag] = 0;
81 }
82 flag++;
83 if (flag == gray[0].length) {
84 return;
85 } else {
86 com(gray, gray.length / 2 - (int) Math.pow(2, (double) flag - 1), gray.length / 2 + (int) Math.pow(2, (double) flag - 1) - 1);
87 }
88 return;
89 }
90 }

 

 

posted on 2011-09-27 23:21  酿皮  阅读(1322)  评论(1)    收藏  举报

导航