题目描述
格雷码是以n位的二进制来表示数。
与普通的二进制表示不同的是,它要求相邻两个数字只能有1个数位不同。
首尾两个数字也要求只有1位之差。
有很多算法来生成格雷码。以下是较常见的一种:
从编码全0开始生成。
当产生第奇数个数时,只把当前数字最末位改变(0变1,1变0)
当产生第偶数个数时,先找到最右边的一个1,把它左边的数字改变。
用这个规则产生的4位格雷码序列如下:
0000
0001
0011
0010
0110
0111
0101
0100
1100
1101
1111
1110
1010
1011
1001
1000
解题思路
由4阶的格雷码 可以看出,格雷码的个数是2n个,且前1\2的第一位为0,后1\2的第一位为1,除了第一位之后其余的几位都是关于1\2处对称的,最后n阶的格雷码也是由n-1阶的格雷码演变而来的,n阶的格雷码就是在n-1阶格雷码的基础上在前半段的首位加上0,后半段的首位加上1,这样最好是用递归来解决。
代码
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String s = scanner.nextLine(); //输出几阶的格雷码
int i = Integer.parseInt(s);
StringBuffer[] sb = n(i);
for(int j=0;j<sb.length;j++){
if(j>0){
System.out.println();
}
System.out.print(sb[j]);
}
}
public static StringBuffer[] n(int n){
int length = (int)Math.pow(2, n); //根据n的值计算格雷码的个数
StringBuffer[] sbArray = new StringBuffer[length];
if(n==1){
sbArray[0] = new StringBuffer("0"); //1阶就只有 0 1
sbArray[1] = new StringBuffer("1");
}else{
StringBuffer[] temp = n(n-1); //递归调用n-1时的格雷码
for(int i=0;i<length;i++){
if(i<length/2){
sbArray[i] = new StringBuffer(temp[i]);
sbArray[i].insert(0, "0");//格雷码中前半部分最高位插入0
}else{
sbArray[i] = new StringBuffer(temp[length-i-1]);
sbArray[i].insert(0, "1");//格雷码中后半部分最高位插入1
}
}
}
return sbArray;
}
}