1. Gray码介绍
Gray码是一个长度为2N的序列,序列中无相同元素,每个元素都是长度为N位的(0,1)串,相邻元素恰好只有一位不同。Gray的特点如下图所示:
此图片来源于以下链接: https://blog.csdn.net/hummingbird0/article/details/105100327.
2.构造方法
设n位Gray码的序列为
G
(
n
)
G(n)
G(n),其倒序列为
G
−
1
(
n
)
G^{-1}(n)
G−1(n),例如
G
(
2
)
=
{
00
,
01
,
11
,
10
}
G(2)= \left\{ 00,01,11,10\right\}
G(2)={00,01,11,10},则
G
−
1
(
2
)
=
{
10
,
11
,
01
,
00
}
G^{-1}(2)= \left\{ 10,11,01,00\right\}
G−1(2)={10,11,01,00};从上图中不难发现以下规律:
G
(
n
)
=
0
G
(
n
−
1
)
+
1
G
−
1
(
n
−
1
)
G(n)=0G(n-1)+1G^{-1}(n-1)
G(n)=0G(n−1)+1G−1(n−1)
从而实现
G
(
n
−
1
)
G(n-1)
G(n−1)到
G
(
n
)
G(n)
G(n)的转化,而初始边界条件
G
(
1
)
=
{
0
,
1
}
G(1)= \left\{ 0,1\right\}
G(1)={0,1}已知。所以,构造Gray码的代码如下:
#include <iostream>
using namespace std;
//构造Gray码 特点是当n大于20后特别占内存
int Gray(int n)
{
if (n < 1) return -1; //输入检测
string* gray = new string[pow(2, n)]; //用字符串数组存储Gray码
int x = 0;
gray[0] = "0"; //边界条件
gray[1] = "1";
for (int i = 2; i <= n; i++) {
x = pow(2, i); //Gray码的规模
for (int m = pow(2, i - 1); m <= (pow(2, i) - 1); m++)
gray[m] = "1" + gray[x - m - 1];
for (int j = 0; j <= (pow(2, i-1) - 1); j++)
gray[j] = "0" + gray[j];
}
for (int i = 0; i < pow(2, n); i++) {
cout << gray[i] << " ";
}
//delete gray;//????????????????为什么此处会报错
return 0;
}
int main()
{
int n;
cout << "请输入一个正整数: ";
cin >> n;
Gray(n);
return 0;
}
此代码用一个字符串数组来存储2n规模的Gray码,显然空间复杂度为O(2n),因此当n比较大的时候特别占内存,呈指数级增长,例如n=25时,就可占4.5GB的内存,当n=29时,会占22GB的运行内存。若有解决此弊端的方法感谢留言告之。