c语言下的回型矩阵

目录

一、背景与感想

二、概念

三、思路

四、编程时间

Wrong 1

Wrong 2

Wrong 3

Wrong 4

四、最终代码


一、背景与感想

在我第一次听说回型矩阵的时候,我是懵逼的,因为我此前根本没听过,于是我上网查询了相关资料,然后稍作了解后,我又不屑一顾,感觉也不过如此,然而在我真正上手编程之后,我才感受到回型矩阵真正的魅力。

我觉得,回型矩阵体现的是一种有规律的代码结构,它近乎是一种回环的建筑与自然之美。

二、概念

首先,不要嫌弃我的图丑(笑),因为条件实在有限(哭)

其次,回型矩阵简单来说正是如图所示的回型结构(从1开始回型赋值),它大多存储在一个二维数组里

                              

三、思路

我么们要实现回型的结构,其实就是不断缩小矩形的大小,所以我们定义了四个变量:top,bottom,left,right,分别代表矩形的顶部,底部,左边,右边

                              

然后,我们需要实现赋值,那么就需要一个在矩形大小不变的情况下能进行变化的量,所以我们需要再定义四个变量(其实一个也可以,不过这里为了便于理解用了四个)t,b,L(大写是为了防止l与1搞混),r.

好了,那么我们开始赋值的过程:

当我们的L大于right的时候,停止顶部赋值,并令top++,如此一来便实现了赋值与矩形的缩小

而接下来,我们只需要重复类似的过程就好,需要变的只是变量的名字,所以我说体现了一种有规律的代码结构

最后当top==bottom && left==right时,则赋值结束

感觉怎么样,似乎,,,也不是很难对吧,嘿嘿,那么我们开始愉快地编程吧

四、编程时间

这一部分我们依旧以错误的形式一步步推进

Wrong 1

首先来看我的代码:

#include<stdio.h>
int main() {
	int a[30][30];//暂定为一个小型矩阵,所以二维数组小一点
	int n = 0;//用户输入矩阵边长
	scanf("%d", &n);
	int top = 0, bottom, left = 0, right,//矩形大小
		L = 0, r, t, b;//四个赋值用的变量
	int count = 1;//用于从1开始赋值
	bottom = n - 1; right = n - 1;
	while (!(top == bottom && left == right)) {//回型赋值//Wrong 1
		while (L <= right) {
			a[top][L] = count;
			count++;
			L++;
		}
		top++; t = top; 
		while (t <= bottom) {
			a[t][right] = count;
			count++;
			t++;
		}
		right--; r = right;
		while (r >= left) {
			a[bottom][r] = count;
			count++;
			r--;
		}
		bottom--; b = bottom;
		while (b >= top) {
			a[b][left] = count;
			count++;
			b--;
		}
		left++; L = left; 
	}
	for (int i = 0; i < n; i++) {//遍历输出
		for (int j = 0; j < n; j++) {
			printf("%-3d ", a[i][j]);
		}
		printf("\n");
	}
	return 0;
}

而运行结果是: 

很明显,这是一个数组越位,至于为什么,其实是因为这是一个死循环,要使循环停止可不是简简单单 !(top == bottom && left == right)而已,我们来看原因:

照我们的代码来看,当最后一个位置被赋值之后其实情况变成了这样:             

 所以跳出循环的条件根本不可能达成,因为两直线相交后只会越走越远错过了就是错过了

so,不分开不就好了(滑稽),那么我们判定一下,当赋值完成(count>n*n)后,我们停止矩形大小(top,bottom,left,right)的变化

那么错误1修正后的代码我们与错误2一并展示

Wrong 2

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main() {
	int a[30][30];//暂定为一个小型矩阵,所以二维数组小一点
	int n = 0;//用户输入矩阵边长
	scanf("%d", &n);
	int top = 0, bottom, left = 0, right,//矩形大小
		L = 0, r, t, b;//四个赋值用的变量
	int count = 1;//用于从1开始赋值
	bottom = n - 1; right = n - 1;
	while (!(top == bottom && left == right)) {//回型赋值
		while (L <= right) {
			a[top][L] = count;
			count++;
			L++;
		}
		if (count <= n * n) { top++; t = top; }
		while (t <= bottom) {
			a[t][right] = count;
			count++;
			t++;
		}
		if (count <= n * n) { right--; r = right; }
		while (r >= left) {
			a[bottom][r] = count;
			count++;
			r--;
		}
		if (count <= n * n) { bottom--; b = bottom; }
		while (b >= top) {
			a[b][left] = count;
			count++;
			b--;
		}
		if (count <= n * n) { left++; L = left; }
	}
    //Wrong 2
	for (int i = 0; i < n; i++) {//遍历输出
		for (int j = 0; j < n; j++) {
			printf("%-3d ", a[i][j]);
		}
		printf("\n");
	}
	return 0;
}

让我们运行一下n=4的情况:

嗯,很完美

但别高兴的太早! 

看看单数的情况:

完蛋,,,BUG又来了

为什么??我们分析一下单数吧:

 不难看出,在最后一步之前就形成了top == bottom && left == right的形式,且刚好一个大while循环结束(这很关键!)所以最后一项未成功赋值

那么我们手动赋值一下吧~

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main() {
	int a[30][30];//暂定为一个小型矩阵,所以二维数组小一点
	int n = 0;//用户输入矩阵边长
	scanf("%d", &n);
	int top = 0, bottom, left = 0, right,//矩形大小
		L = 0, r, t, b;//四个赋值用的变量
	int count = 1;//用于从1开始赋值
	bottom = n - 1; right = n - 1;
	while (!(top == bottom && left == right)) {//回型赋值
		while (L <= right) {
			a[top][L] = count;
			count++;
			L++;
		}
		if (count <= n * n) { top++; t = top; }
		while (t <= bottom) {
			a[t][right] = count;
			count++;
			t++;
		}
		if (count <= n * n) { right--; r = right; }
		while (r >= left) {
			a[bottom][r] = count;
			count++;
			r--;
		}
		if (count <= n * n) { bottom--; b = bottom; }
		while (b >= top) {
			a[b][left] = count;
			count++;
			b--;
		}
		if (count <= n * n) { left++; L = left; }
	}
	a[top][left] = count; //手动为最后一项赋值//Wrong 3
	for (int i = 0; i < n; i++) {//遍历输出
		for (int j = 0; j < n; j++) {
			printf("%-3d ", a[i][j]);
		}
		printf("\n");
	}
	return 0;
}

运行一下吧:

 

很好,这样最后一项就妥了

但这也带来了Wrong 3。。。

Wrong 3

如果我们回归到n为偶数的情况会如何呢?

很遗憾,因为偶数在循环内就完成了最后一项赋值,所以最后反而画蛇添足了

所以我们进行最后一项赋值时,不如判断一下n的奇偶,再做赋值

又考虑到代码堆在main函数里太臃肿,所以我们把回型赋值包装成一个函数拿出来

这就完了?其实并没有。万万没想到,最后打败我的是n<2的情况。。

Wrong 4

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
void return_matrix(int a[][30], int n) {
	int top = 0, bottom, left = 0, right,//矩形大小
		L = 0, r, t, b;//四个赋值用的变量
	int count = 1;//用于从1开始赋值
	bottom = n - 1; right = n - 1;
	while (!(top == bottom && left == right)) {//回型赋值
		while (L <= right) {
			a[top][L] = count;
			count++;
			L++;
		}
		if (count <= n * n) { top++; t = top; }
		while (t <= bottom) {
			a[t][right] = count;
			count++;
			t++;
		}
		if (count <= n * n) { right--; r = right; }
		while (r >= left) {
			a[bottom][r] = count;
			count++;
			r--;
		}
		if (count <= n * n) { bottom--; b = bottom; }
		while (b >= top) {
			a[b][left] = count;
			count++;
			b--;
		}
		if (count <= n * n) { left++; L = left; }
	}
	if (n % 2 != 0) { a[top][left] = count; }//对n为单数的情况进行最后一项的赋值
}
int main() {
	int a[30][30];//暂定为一个小型矩阵,所以二维数组小一点
	int n = 0;//用户输入矩阵边长
	scanf("%d", &n);
	return_matrix(a, n);
	for (int i = 0; i < n; i++) {//遍历输出
		for (int j = 0; j < n; j++) {
			printf("%-3d ", a[i][j]);
		}
		printf("\n");
	}
	return 0;
}

运行一下:

很完美,如果没有下面这个。。。

摆烂了,直接面向结果编程:看看最终代码吧:

四、最终代码

#include<stdio.h>
void return_matrix(int a[][30], int n) {
	int top = 0, bottom, left = 0, right,//矩形大小
		L = 0, r, t, b;//四个赋值用的变量
	int count = 1;//用于从1开始赋值
	bottom = n - 1; right = n - 1;
    if(n==2){
        a[0][0]=1;
        a[0][1]=2;
        a[1][0]=4;
        a[1][1]=3;
    }
    else if(n==1) a[0][0]=1;
	else {
        while (!(top == bottom && left == right)) {//回型赋值
		while (L <= right) {
			a[top][L] = count;
			count++;
			L++;
		}
		if (count <= n * n) { top++; t = top; }
		while (t <= bottom) {
			a[t][right] = count;
			count++;
			t++;
		}
		if (count <= n * n) { right--; r = right; }
		while (r >= left) {
			a[bottom][r] = count;
			count++;
			r--;
		}
		if (count <= n * n) { bottom--; b = bottom; }
		while (b >= top) {
			a[b][left] = count;
			count++;
			b--;
		}
		if (count <= n * n) { left++; L = left; }
	}
	if (n % 2 != 0) { a[top][left] = count; }
    }//对n为单数的情况进行最后一项的赋值
}
int main() {
	int a[30][30];//暂定为一个小型矩阵,所以二维数组小一点
	int n = 0;//用户输入矩阵边长
	scanf("%d", &n);
	return_matrix(a, n);
	for (int i = 0; i < n; i++) {//遍历输出
        int j;
		for (j = 0; j < n-1; j++) {
			printf("%03d ", a[i][j]);
		}
        printf("%03d\n", a[i][j]);
	}
	return 0;
}

运行一下(稍微改了下输出格式): 

 

感谢观看~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冬有雪的学习之路

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值