自动生成格雷码算法

典型的二进制格雷码(Binary Gray Code)简称格雷码,在一组数的编码中,若任意两个相邻的代码只有一位二进制数不同,则称这种编码为格雷码(Gray Code),另外由于最大数与最小数之间也仅一位数不同,即“首尾相连”,因此又称循环码反射码

自动生成格雷码的算法主要利用以下规则:

1. 1位格雷码有两个码字。
2. (n+1)位格雷码中的前2n个码字等于n位格雷码的码字,按顺序书写,加前缀0。
3. (n+1)位格雷码中的后2n个码字等于n位格雷码的码字,按逆序书写,加前缀1。
4. (n+1)位格雷码的集合 = n位格雷码集合(顺序)加前缀0 + n位格雷码集合(逆序)加前缀1。

简而言之,就是后面的格雷码等于其相邻的前面的格雷码按顺序书写,加前缀0,再按逆序书写,加前缀1如下图所示:

自动生成格雷码算法

按照这个思路很容易的实现代码:

[cpp] view plain copy
  1. void generaterGrayCode(int n)  
  2. {  
  3.     vector<string> grayCodeVec;  
  4.   
  5.     //当n为1的时候的格雷码  
  6.     string aa = "0";  
  7.     string bb = "1";  
  8.     grayCodeVec.push_back(aa);  
  9.     grayCodeVec.push_back(bb);  
  10.   
  11.     //产生大于两位的格雷码,n位格雷码的数量为2^n个  
  12.     if (n > 1)  
  13.     {  
  14.         for (int i = 2; i <= n; i++)  
  15.         {  
  16.             //设置一个临时存储空间来存储n-1位格雷码  
  17.             vector<string> tempGrayCodeVec;  
  18.             for (size_t k = 0; k < grayCodeVec.size(); k++)  
  19.             {  
  20.                 tempGrayCodeVec.push_back(grayCodeVec[k]);  
  21.             }  
  22.   
  23.             //在前面产生的n-1位格雷码前面添加一位数0产生2^(n-1)个n位格雷码,并替换掉原来的n-1位格雷码  
  24.             int tempGrayCodeVecSize = tempGrayCodeVec.size();  
  25.             for (int j = 0; j < tempGrayCodeVecSize; j++)  
  26.             {  
  27.                 string tempbitzero = "0";  
  28.                 tempbitzero += tempGrayCodeVec[j];  
  29.                 grayCodeVec[j] = tempbitzero;  
  30.             }  
  31.   
  32.             //将前面产生的n-1位格雷码的顺序反转  
  33.             //在反转后的n-1位格雷码前面添加一位数1产生剩下2^(n-1)个n位格雷码,并存储起来  
  34.             for (int jj = tempGrayCodeVecSize-1; jj >= 0; jj--)  
  35.             {  
  36.                 string tempbitone = "1";  
  37.                 tempbitone += tempGrayCodeVec[jj];  
  38.                 grayCodeVec.push_back(tempbitone);  
  39.             }  
  40.             //释放掉临时存储空间  
  41.             tempGrayCodeVec.clear();  
  42.         }  
  43.     }  
  44.   
  45.     //输出n位格雷码  
  46.     for (size_t i = 0; i < grayCodeVec.size(); i++)  
  47.     {  
  48.         cout << grayCodeVec[i] << endl;  
  49.     }  
  50.     cout << endl;  
  51. }