浅谈格雷码 (分治法)

题目:
在这里插入图片描述
分治法:故名思意,分而治之
下面我们就分开它,然后搞死它,谁叫它让我们掉发

思路

假设,我们现在要构造n值相对应的格雷码,我们可以先把n-1值对应的格雷码中心对称分给下半部分,这样子的话,我们除了对称两边第一行这对不满足我们的条件,其他的相邻对都满足了,然后我们还有最后一列可以让我们发挥。

说到这里大家可能有点糊涂了:我用图来说话
浅谈格雷码 (分治法)_第1张图片
用红色圈住这两个东西,由于我们对称复制,所以这两框中一 一对应元素相同,我们要这两行有差异,我们就让最后一列元素和红框1同行的为0,和红框2同行的为1。(ps:0和1互换位置可以吗?)

说到这里不知道你们悟了没有

最后一个思路讲解就结束这个痛苦的思路过程了,坚持啊战士们

切入正题:因为除了我们前面说的两个红框数据有问题,其他的相邻都是有一位存在差异的(因为我们默认它们是n-1位格雷码了),所以最后一列我们要保证相邻的要相同才行,== 这样,最后一列0前面的都是0,1后面的都是1

这样我们就能保证它们相邻只差一位不同了,最后一列的样子如图所示:

浅谈格雷码 (分治法)_第2张图片

好奇的读者就发现了,这些元素的十进制一直从0开始递增到2^n-1才能的,确实如此,因为每一行都不相同,又有2 ^ n行,这不就把所有n个01的可能都包揽了(这是废话,可以不看)

代码分析

n:n位格雷码

a: a = 2^ n

浅谈格雷码 (分治法)_第3张图片

上面我都标注了框1,2,3,4;接下来我说一下每个框中代码的作用

框1:函数的出口,就是n=1的时候,我们要填入什么,上面填0,下面填1吧。

框2:就是我们上面说到的 处理 n位 格雷码最后一列的东西

框3:函数的递归,就是将n-1位的格雷码填入这个二维数组中

框4:就是呈中心对称的形式复制n-1位格雷码到下面去

到这里函数终于结束了,你们也解放了

我都这么努力了,不点个赞和关注在走吗?

完整代码:

#include
#include
using namespace std;

int ans[1024][1024];

void Graeme(int n,int a) {
     
	if(n==1){
     
		ans[0][0] = 0;
		ans[1][0] = 1;
		return ;
	}
	for(int i=0;i<a/2;i++) {
     
		ans[i][n-1] = 0;
		ans[a-i-1][n-1] = 1;
	}
	Graeme(n-1,a/2);
	for(int i=a/2;i<a;i++) {
     
		for(int j=0;j<n-1;j++) {
     
			ans[i][j] = ans[a-i-1][j];
		}
	}
}

int main() {
     
	int n;
	cout<<"输入格雷码位数:";
	cin>>n;
	int a = pow(2,n);//总位数 
	Graeme(n,a);
	cout<<"输出格雷码:"<<endl;
	for(int i=0;i<a;i++) {
     
		for(int j=0;j<n;j++) {
     
			cout<<ans[i][j];
		}
		cout<<endl;
	}
	return 0;
}

点个关注,不迷路

作者:随风

哪里讲错了也可以私信我:2338244917(qq)

ps: 上面我提过01可以替换吗?替换了要注意什么,如果大家感兴趣的话,可以加qq:2338244917,我们可以讨论一波

你可能感兴趣的:(算法,算法)