一个回环矩阵的程序设计实例
2015-11-08 16:17
357 查看
这个问题挺有意思,严苛的表达形式为:
对于任意指定的一个输入规模n,要求输出起始方向向右的回环矩阵。
比如:n = 3
输出:1 2 3
8 9 4
7 6 5
比如:n = 5
输出:1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9
这个题目还是在csdn技术问答社区看到的,当时我以为自己10分钟也许就能够写好代码,没想到还是捣鼓了一个小时。
在我看来,此题并不难,但是设计到一个设计模式的问题:我要去观察它们的特征好用数学方程来描述还是把一切交给程序按部就班去做就行了呢?
经历了激烈的思想斗争,我还是打算做一个什么都不懂的指挥官,还是让程序自己运作吧,而我唯一需要做的就是:指定初始条件,设计变化边界。
因此,也没什么好说的,附上代码:
当把NUM设置为15时,测试结果为:
分析上述程序的思路,其实非常容易看明白:
第一,设置一个二维数组,i代表行,j代表列,这样数与数组元素之间的对应关系就非常容易找到;
第二,设计四个动作函数,向右,向下,向左,向上,而我们知道它是可以串起来并且有序的,所以动作循环就是:右->下->左->上->右…;
第三,设置动作变化的边界条件:容易看出,就那么两条,一是到边了没法在往前走了,二是本来该走的位置已经有数了,符合任何一条都得转向。
整个设计要点也就以上三个,不麻烦。但是以上程序却有两个大问题:
第一,代码冗长,平均每行代码效率低下;
第二,而且函数之间相关度太高,缺乏独立性。
如果大家看了有自己的思考,欢迎拍砖灌水哦~
后话
我记得我的网络软件设计老师说:不是去写程序,而是设计程序;编程到深处,与写文章并无二异。 这句话可能不一定对,却引导我走上了计算机科学学习的道路。万卷归宗,百川到海。我们在不同领域所探索的不同谜题,也许都有着同样的谜底 。
致谢:感谢你的阅读,风云际会,即是有缘。祝 一路顺风!*
对于任意指定的一个输入规模n,要求输出起始方向向右的回环矩阵。
比如:n = 3
输出:1 2 3
8 9 4
7 6 5
比如:n = 5
输出:1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9
这个题目还是在csdn技术问答社区看到的,当时我以为自己10分钟也许就能够写好代码,没想到还是捣鼓了一个小时。
在我看来,此题并不难,但是设计到一个设计模式的问题:我要去观察它们的特征好用数学方程来描述还是把一切交给程序按部就班去做就行了呢?
经历了激烈的思想斗争,我还是打算做一个什么都不懂的指挥官,还是让程序自己运作吧,而我唯一需要做的就是:指定初始条件,设计变化边界。
因此,也没什么好说的,附上代码:
#include "stdio.h" #include "stdlib.h" #define NUM 10 void right_add(int a[NUM][NUM],int line,int row,int count); //Note that it can't be written as a[][] here(with an error called "Without subscript") void down_add(int a[NUM][NUM],int line,int row,int count); void left_add(int a[NUM][NUM],int line,int row,int count); void up_add(int a[NUM][NUM],int line,int row,int count); void print(int a[NUM][NUM],int n); int main(int argc, char* argv[]) { int i,j; int result[NUM][NUM]; for(i = 0;i < NUM;i++) for(j = 0;j < NUM;j++) result[i][j] = 0; int num = NUM * NUM; right_add(result,0,0,1); //The first move is always towards right return 0; } void right_add(int a[NUM][NUM],int line,int row,int count) { //Move to right position until there are limits while(a[line][row] == 0) { a[line][row] = count; count++; if (count > NUM*NUM) { print(a,NUM); exit(0); } row++; if(row % NUM == 0 || a[line][row] != 0) { //When it reaches the border or its right is a valid number,goto down_add row--; line++; down_add(a,line,row,count); } } } void down_add(int a[NUM][NUM],int line,int row,int count) { //Move to downside position until there are limits while(a[line][row] == 0) { a[line][row] = count; count++; if (count > NUM*NUM) { print(a,NUM); exit(0); } line++; if(line % NUM == 0 || a[line][row] != 0) { //When it reaches the border or its downside is a valid number,goto left_add line--; row--; left_add(a,line,row,count); } } } void left_add(int a[NUM][NUM],int line,int row,int count) { //Move to left position until there are limits while(a[line][row] == 0) { a[line][row] = count; count++; if (count > NUM*NUM) { print(a,NUM); exit(0); } row--; if(row == -1 || a[line][row] != 0) { //When it reaches the border or its upside is a valid number,goto up_add row++; line--; up_add(a,line,row,count); } } } void up_add(int a[NUM][NUM],int line,int row,int count) { //Move to upside position until there are limits while(a[line][row] == 0) { a[line][row] = count; count++; if (count > NUM*NUM) { print(a,NUM); exit(0); } line--; if(line == -1 || a[line][row] != 0) { //When it reaches the border or its upper is a valid number,goto right_add line++; row++; right_add(a,line,row,count); } } } void print(int a[NUM][NUM],int n) { //Print out the result we get int i,j; printf("The result for scale=%d\n",NUM); for(i = 0;i < n;i++) { for(j = 0;j < n;j++) { printf("%4d",a[i][j]); //Formatting the output if ((j+1) % n == 0) //goto next line printf("\n"); } } }
当把NUM设置为15时,测试结果为:
分析上述程序的思路,其实非常容易看明白:
第一,设置一个二维数组,i代表行,j代表列,这样数与数组元素之间的对应关系就非常容易找到;
第二,设计四个动作函数,向右,向下,向左,向上,而我们知道它是可以串起来并且有序的,所以动作循环就是:右->下->左->上->右…;
第三,设置动作变化的边界条件:容易看出,就那么两条,一是到边了没法在往前走了,二是本来该走的位置已经有数了,符合任何一条都得转向。
整个设计要点也就以上三个,不麻烦。但是以上程序却有两个大问题:
第一,代码冗长,平均每行代码效率低下;
第二,而且函数之间相关度太高,缺乏独立性。
如果大家看了有自己的思考,欢迎拍砖灌水哦~
后话
我记得我的网络软件设计老师说:不是去写程序,而是设计程序;编程到深处,与写文章并无二异。 这句话可能不一定对,却引导我走上了计算机科学学习的道路。万卷归宗,百川到海。我们在不同领域所探索的不同谜题,也许都有着同样的谜底 。
致谢:感谢你的阅读,风云际会,即是有缘。祝 一路顺风!*
相关文章推荐
- 《verilog数字系统设计教程》书评
- javascript遍历JSON
- position的用法
- 《STL源码剖析》深入分析序列式容器——deque
- hdoj 1495 非常可乐
- 10-24作业总结
- HDU - 1231 最大连续子序列
- 野人学Android第二弹——自定义ListView第二课
- UIApplication相关
- 数据存储技术
- Unity3d通用工具类之数据配置加载类
- Android(10):时间与日期TimePicker、DatePicker、模拟时钟(非数字时钟)AnalogcClock
- 【Java】 变量和编译时类型和运行时类型不同
- <仅是自己做笔记。。。系列-12>输入一个表示整数的字符串,把该字符串转换成整数并输出。
- Unity3d通用工具类之数据配置加载类
- Java学习笔记(十)——多态
- android studio 如何设置代码区域的背景色
- 如何反编译APK?
- Android 效率开发之EventBus新使用方法
- 如何反编译APK?