问题描述
Gray码是一个长度为2n的序列。序列中无相同元素,每个元素都是长度为n位的(0,1)串,相邻元素恰好只有一位不同。用分治策略设计一个算法对任意的n构造相应的Gray码。
分析与解答
Gray码
长度(位) | (0,1)串 | |||
n=1 | 0 | 1 | ||
n=2 | 00 | 01 | ||
11 | 10 | |||
n=3 | 000 | 001 | 011 | 010 |
110 | 111 | 101 | 100 |
考察n=1, 2, 3的简单情形,如上表所示。
设n位Gray码序列为G(n), G(n)以相反顺序排列的序列为G-1(n)。从上面的简单情形可以看出G(n)的构造规律:G(n+1)=0G(n) 1G-1(n) 。
例如:当n=1时,G(n+1) = 0G(1) 1G-1(1) = 0{0, 1} 1{1, 0}
得:00 01 11 10
注意到G(n)的最后一个n位串与G-1(n)的第一个n位串相同,可用数学归纳法证明G(n)的上述构造规律。
实现代码
public class Gray {
public static void main(String[] args) {
int[] a = new int[1024];
gray(a, 1);
out(a, 1);
gray(a, 2);
out(a, 2);
gray(a, 3);
out(a, 3);
}
/**
* 将n位(0,1)串看成二进制数,第i个串存储在a[i]中
*
* @param a gray码序列
* @param length 长度
*/
public static void gray(int[] a, int length) {
if (length == 1) {
a[1] = 0;
a[2] = 1;
return;
}
gray(a, length - 1);
for (int k = 1 << (length - 1), i = k; i > 0; i--) {
// G(n) = 0G(n-1) 1G(n-1)
// a[1...k]已构造, a[i]+k相当于在a[i]前加上前缀1
a[2 * k - i + 1] = a[i] + k;
}
}
/**
* 输出gray码序列
*
* @param a gray码序列
* @param length 长度
*/
public static void out(int[] a, int length) {
int m = 1 << length;
for (int i = 1; i <= m; i++) {
StringBuilder str = new StringBuilder();
// 把a[i]转成二进制串
String temp = Integer.toString(a[i], 2);
int sLen = temp.length();
for (int j = 0; j < length - sLen; j++) {
str.append("0");
}
str.append(temp);
System.out.print(str.toString() + " ");
}
System.out.println();
}
}