c++语言分治策略生成Gray码
程序员文章站
2022-07-12 12:50:03
...
Gray码是一个长度为2^n的序列。序列中无相同元素,每个元素都是长度为n的(0,1)串,相邻的元素恰好只有一位不同。
下面列举几个低位格雷码
1位格雷码(2^1=2) | 2位格雷码(2^2=4) | 3位格雷码(2^3=8) | 4位格雷码(2^4=16) | 其他… |
---|---|---|---|---|
0 | 00 | 000 | 0000 | … |
1 | 01 | 001 | 0001 | |
11 | 011 | 0011 | ||
10 | 010 | 0010 | ||
110 | 0110 | |||
111 | 0111 | |||
101 | 0101 | |||
100 | 0100 | |||
1100 | ||||
1101 | ||||
1111 | ||||
1110 | ||||
1010 | ||||
1011 | ||||
1001 | ||||
1000 |
从上面的表格不难得出:
- 1位格雷码有两个码字0,1
- (n+1)位格雷码中的前2^n个码字等于n位格雷码的码字,按顺序书写,加前缀0
- (n+1)位格雷码中的后2^n个码字等于n位格雷码的码字,按逆序书写,加前缀1
- n+1位格雷码的集合 = n位格雷码集合(顺序)加前缀0 + n位格雷码集合(逆序)加前缀1
使用二维数组以及递归来解决问题:
- n = 1, arr[0][0] = 0, arr[1][0] = 1
- n > 1,递归图示如下:
0 | 1 | 2 | 3 | 4 | … | n | |
---|---|---|---|---|---|---|---|
0 | 0 | 0 | 0 | ||||
1 | 1 | 0 | 0 | ||||
2 | 1 | 1 | 0 | ||||
3 | 0 | 1 | 0 | ||||
4 | 0 | 1 | 1 | ||||
5 | 1 | 1 | 1 | ||||
6 | 1 | 0 | 1 | ||||
7 | 0 | 0 | 1 | ||||
… | |||||||
n |
输出Gray码时,从右往左输出
#include <iostream>
#include<math.h>
using namespace std;
void Gray(int **arr,int sum, int n) { //Gray生成函数
if (n == 1) {
arr[0][0] = 0;
arr[1][0] = 1;
return;
}
Gray(arr,sum / 2, n - 1);
for (int i = 0; i < sum / 2; i++) { //循环作用为添加 0 和 1
arr[i][n - 1] = 0;
arr[sum - i - 1][n - 1] = 1;
}
for (int i = sum / 2; i < sum; i++) { //循环作用为 倒序复制
for (int j = 0; j < n - 1; j++)
arr[i][j] = arr[sum - i - 1][j];
}
}
int main()
{
int n;
int** arr;
cout << "输入n: ";
cin >> n;
int sum = pow(2, n);
arr = new int* [sum]; //动态二维数组
for (int i = 0; i < sum; i++)
arr[i] = new int[n];
Gray(arr, sum, n); //生成格雷码
for (int i = 0; i < sum; i++) { //输出,方向为右向左 ←
for (int j = n-1; j>=0 ; j--)
{
cout << arr[i][j];
}
cout << endl;
}
for (int i = 0; i < sum; i++) //释放内存
delete[] arr[i];
delete[] arr;
return 0;
}
运行效果图
如果觉得这篇文章对你有用,请点个赞吧~ pwp ~°
下一篇: postman传数组
推荐阅读