您的位置:首页 > 其它

一个回环矩阵的程序设计实例

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分钟也许就能够写好代码,没想到还是捣鼓了一个小时。

在我看来,此题并不难,但是设计到一个设计模式的问题:我要去观察它们的特征好用数学方程来描述还是把一切交给程序按部就班去做就行了呢?

经历了激烈的思想斗争,我还是打算做一个什么都不懂的指挥官,还是让程序自己运作吧,而我唯一需要做的就是:指定初始条件,设计变化边界。

因此,也没什么好说的,附上代码:

#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代表列,这样数与数组元素之间的对应关系就非常容易找到;

第二,设计四个动作函数,向右,向下,向左,向上,而我们知道它是可以串起来并且有序的,所以动作循环就是:右->下->左->上->右…;

第三,设置动作变化的边界条件:容易看出,就那么两条,一是到边了没法在往前走了,二是本来该走的位置已经有数了,符合任何一条都得转向。

整个设计要点也就以上三个,不麻烦。但是以上程序却有两个大问题:

第一,代码冗长,平均每行代码效率低下;

第二,而且函数之间相关度太高,缺乏独立性。

如果大家看了有自己的思考,欢迎拍砖灌水哦~

后话

我记得我的网络软件设计老师说:不是去写程序,而是设计程序;编程到深处,与写文章并无二异。 这句话可能不一定对,却引导我走上了计算机科学学习的道路。万卷归宗,百川到海。我们在不同领域所探索的不同谜题,也许都有着同样的谜底 。

致谢:感谢你的阅读,风云际会,即是有缘。祝 一路顺风!*
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: