首先先看维基百科给出的格雷码的定义,以及了解一下为什么要有格雷编码这种编码方式,然后还有三种生成格雷的方式,本文实现了前两种生成格雷码的方式。
直接排列法
生成n位的锁有格雷码,首先n位全0,下一个数是最右边的bit取反(异或1),下一个数是最右边为1的bit位左边那个bit位取反。这样循环往复下去。直到生成2^n个格雷码
class Solution {
public:
int mostRightOneIndex(int num) //求一个数的二进制中最右边的1的出现在哪一位上
{
int x = 0x1;
int index = 0;
while(num)
{
if((num & 0x1) == 0x1)
{
return index;
}
else
{
num = num >> 1;
index++;
}
}
return -1;
}
vector<int> grayCode(int n) {
vector<int> res;
res.push_back(0);
if(n == 0)
return res;
bool flag = true; //用来指示变换规则
for(int i = 1; i < pow(2, n); ++i)
{
if(flag) //最右边bit取反
{
res.push_back(res.back() ^ 0x1);
flag = false;
}
else //最右边的1的左边bit位取反
{
int last_num = res.back();
int index = mostRightOneIndex(last_num);
last_num ^= (1 << (index + 1));
res.push_back(last_num);
flag = true;
}
}
return res;
}
};
镜像生成法
class Solution {
public:
vector<string> generateGrayCode(int n)
{
vector<string> res;
res.push_back(string("0"));
res.push_back(string("1"));
for(int i = 1; i < n; ++i)
{
int temp_size = res.size();
for(int j = 0; j < res.size(); ++j)
{
res[j] = '0' + res[j];
}
for(int j = temp_size - 1; j >= 0; --j)
{
res.push_back('1' + res[j].substr(1, res[j].length()));
}
}
return res;
}
vector<int> grayCode(int n) {
vector<int> res;
if(n == 0)
{
res.push_back(0);
return res;
}
vector<string> str_res = generateGrayCode(n);
for(auto t : str_res)
{
res.push_back((int)bitset<32>(t).to_ulong());
}
return res;
}
};