#include <iostream>
#include <stdio.h>
#include <vector>
using namespace std;
/*
问题:
The gray code is a binary numeral system where two successive values differ in only one bit.
Given a non-negative integer n representing the total number of bits in the code, print the sequence of gray code. A gray code sequence must begin with 0.
For example, given n = 2, return [0,1,3,2]. Its gray code sequence is:
00 - 0
01 - 1
11 - 3
10 - 2
Note:
For a given n, a gray code sequence is not uniquely defined.
For example, [0,2,3,1] is also a valid gray code sequence according to the above definition.
For now, the judge is able to judge based on one instance of gray code sequence. Sorry about that.
分析:
格雷码
一般的,普通二进制码与格雷码可以按以下方法互相转换:
二进制码->格雷码(编码):从最右边一位起,依次将每一位与左边一位异或(XOR),作为对应格雷码该位的值,最左边一位不变(相当于左边是0);
格雷码-〉二进制码(解码):从左边第二位起,将每位与左边一位解码后的值异或,作为该位解码后的值(最左边一位依然不变)
此题是要模拟格雷码,通过给定的二进制数的位数n,求出连续相邻数字仅有1个二进制位不同的整数序列。
关键就是看每次决定变换哪一位,需要找到规律。
00 初始值
01 修改右边第一位
11 修改右边第二位
10 修改右边第一位
因此递归步骤是:初始时设定格雷码首个数字为0
如果 n = 0,直接返回,返回0
如果 n = 1,让n = n^1,做异或,实际就是生成1,并将1加入结果集
如果 n > 1,先使得右边第n位(也就是最高位)变成1【可以与2^(n-1)异或即可?】,将数字插入到结果集
保证最左侧为1,然后生成长度为n-1的格雷码,并将该格雷码插入结果集
输入:
2
输出:
0 1 3 2
关键:
1 此题是要模拟格雷码,通过给定的二进制数的位数n,求出连续相邻数字仅有1个二进制位不同的整数序列。
关键就是看每次决定变换哪一位,需要找到规律。
2 变位从0变1或者从1变0,肯定用异或
00 初始值
01 修改右边第一位
11 修改右边第二位
10 修改右边第一位
因此递归步骤是:初始时设定格雷码首个数字为0
如果 n = 0,直接返回,返回0
如果 n = 1,让n = n^1,做异或,实际就是对最右边进行变位,并将结果加入结果集
如果 n > 1,先计算最高位没有变位的长度为n-1的格雷码【1】
然后使得右边第n位(也就是最高位)变位【可以与2^(n-1)异或即可,异或才能变位】,将结果插入到结果集
保证最高位变位后,然后生成长度为n-1的格雷码,并将该格雷码插入结果集【3】
2
//如果只有一位,就将当前值的最右边变成1,与1异或即可
if(1 == n)
{
curNum ^= 1;//这里使得最右边进行了变位,从1变成0或者从0变成1
result.push_back(curNum);
}
//先产生长度为n-1的格雷码,此时最高位默认为0或1,得到最右边为0的所有格雷码
//然后使得修改第n位变成1或0【这里为了实现变位,将第n位与2的n-1次方进行异或】,得到最右边为1的所有格雷码,
else
{
getGrayCode(n-1 , result , curNum);
curNum ^= (1 << (n-1));//设置最高位进行变位
result.push_back(curNum);//变位后的格雷码需要插入
getGrayCode(n-1 , result , curNum);//这里之所以还有一个递归,是因为,对最高位变位后,需要产生最高位变位后的所有格雷码
}
*/
class Solution {
public:
void getGrayCode(int n , vector<int>& result , int& curNum )
{
//如果n=0,结果集已经存入了0,直接返回
if(0 == n)
{
return;
}
//如果只有一位,就将当前值的最右边变成1,与1异或即可
if(1 == n)
{
curNum ^= 1;//这里使得最右边进行了变位,从1变成0或者从0变成1
result.push_back(curNum);
}
//先产生长度为n-1的格雷码,此时最高位默认为0或1,得到最右边为0的所有格雷码
//然后使得修改第n位变成1或0【这里为了实现变位,将第n位与2的n-1次方进行异或】,得到最右边为1的所有格雷码,
else
{
getGrayCode(n-1 , result , curNum);
curNum ^= (1 << (n-1));//设置最高位进行变位
result.push_back(curNum);//变位后的格雷码需要插入
getGrayCode(n-1 , result , curNum);//这里之所以还有一个递归,是因为,对最高位变位后,需要产生最高位变位后的所有格雷码
}
}
vector<int> grayCode(int n) {
vector<int> result;
result.push_back(0);//压入任何数都需要的格雷码:0
int curNum = 0;//初始化当前格雷码为1
getGrayCode(n , result , curNum);
return result;
}
};
void print(vector<int>& result)
{
if(result.empty())
{
cout << "no result" << endl;
return;
}
int size = result.size();
for(int i = 0 ; i < size ; i++)
{
cout << result.at(i) << " " ;
}
cout << endl;
}
void process()
{
vector<int> nums;
int value;
int num;
Solution solution;
vector<int> result;
while(cin >> num )
{
result = solution.grayCode(num);
print(result);
}
}
int main(int argc , char* argv[])
{
process();
getchar();
return 0;
}