简述“自顶向下,逐步求精”——面向过程程序设计方法
2017-11-28 00:09
771 查看
引入
所谓“自顶向下,逐步求精”的程序设计方法,网络上有着如下的说法,一者是百度百科所述,另一者则为维基百科的说法。自顶向下设计 :一种逐步求精的设计程序的过程和方法。对要完成的任务进行分解,先对最高层次中的问题进行定义、设计、编程和测试,而将其中未解决的问题作为一个子任务放到下一层次中去解决。这样逐层、逐个地进行定义、设计、编程和测试,直到所有层次上的问题均由实用程序来解决,就能设计出具有层次结构的程序。
——百度百科
In computer science, divide and conquer is an algorithm design paradigm based on multi-branched recursion. A divide and conquer algorithm works by recursively breaking down a problem into two or more sub-problems of the same or related type, until these become simple enough to be solved directly. The solutions to the sub-problems are then combined to give a solution to the original problem.
——Wikipedia
个人看法
要说到“自顶向下”,那么肯定是有着一个顶部的存在——就是一个或若干个复杂的大的问题。那么将这复杂、大的问题划分为小问题,找出问题的关键、重点所在,然后用精确的思维定性、定量地去描述问题,就是“自顶向下”方法的思路和体现。至于“逐步求精”,那就是将现实世界的问题经抽象转化为逻辑空间或求解空间的问题。复杂问题经抽象化处理变为相对比较简单的问题。经若干步抽象(精化)处理,最后到求解域中只是比较简单的编程问题。
其中,具体可分为以下几钟不同的抽象处理方式:
①顺序结构
②选择结构
③循环结构
而其中最复杂的要数循环结构,但这种方法却是解决问题较为有效的一种方法,比如说它可以解决洗衣机运行的问题,而今日我就将用这种“自顶向下,逐步求精”的方法实现普通洗衣机运行程序的伪代码。
不过在这之前,我得先用一个简单的例子来熟悉熟悉这一种方法。
例1:杨辉三角
例1:输入一个数字n(1<=n<=10), 不在范围内的n输出“Out Of Range.\n” 输出杨辉三角的前n行为什么我会选择杨辉三角来充当本文的第一个例子而不选择简单的1+2+3+…+n这种问题来充当例子呢?
&esmp;很简单,那种1加到100的问题逼格不够,一看就是拿来敷衍的。(吐槽一发)
那么,这个杨辉三角怎么样才能够用代码实现呢?
方法有很多,因为这个数阵这么多年来早已经被人类给摸得七七八八了:
规律:
从上图可看出杨辉三角的几个显著特征:
1. 每行数值左右对称,且均为正整数。 2. 行数递增时,列数亦递增。 3. 除斜边上的1外,其余数值均等于其肩部两数之和。
①先提一种较为直观的方法, 杨辉三角与二项式定理有密切关系,即杨辉三角的第n行(n=0…MAX_ROW)对应二项式(a+b)n展开(Binomial Expansion)的系数集合
。例如,第二行的数值1-2-1为幂指数为2的二项式(a+b)^2展开形式a^2 + 2ab + b^2的系数,即
组合后得到:
故 直接利用特征3求解杨辉值,即第i行的第j个数等于第i-1行的第j-1个数与第j个数之和,用二维数组形式表达即为a[i][j] = a[i-1][j-1] + a[i-1][j],通俗易懂简洁。
代码实现:
1 void BasicYangHui(void) 2 { 3 int dwRow = 0, dwCol = 0, aTriVal[MAX_ROW][MAX_COL] = {{0}}; 4 5 for(dwRow = 0; dwRow < MAX_ROW; dwRow++) 6 { 7 aTriVal[dwRow][0] = aTriVal[dwRow][dwRow] = 1; //若为i行0或i列,则i行j列杨辉值为1 8 } 9 10 for(dwRow = 2; dwRow < MAX_ROW; dwRow++) 11 { 12 for(dwCol = 1; dwCol < dwRow; dwCol++) //否则,i行j列杨辉值为i-1行中第j-1列与第j列值之和 13 aTriVal[dwRow][dwCol] = aTriVal[dwRow-1][dwCol-1] + aTriVal[dwRow-1][dwCol]; 14 } 15 16 //输出杨辉三角值 17 for(dwRow = 0; dwRow < MAX_ROW; dwRow++) 18 { 19 for(dwCol = 0; dwCol <= dwRow; dwCol++) 20 { 21 printf("%5d", aTriVal[dwRow][dwCol]); 22 } 23 printf("\n"); 24 } 25 }
②我要是连数组都懒得用呢,好的,也可以,这就需要继续找规律咯(我贴出代码,至于规律,则是已深在其中)。
int main() { int s = 1, h; // 数值和高度 int i, j; // 循环计数 scanf("%d", &h); // 输入层数 printf("1\n"); // 输出第一个 1 for (i = 2; i <= h; s = 1, i++) // 行数 i 从 2 到层高 { printf("1 "); // 第一个 1 for (j = 1; j <= i - 2; j++) // 列位置 j 绕过第一个直接开始循环 //printf("%d ", (s = (i - j) / j * s)); printf("%d ", (s = (i - j) * s / j)); printf("1\n"); // 最后一个 1,换行 } getchar(); // 暂停等待 return 0; }
如图:
这就轻松完成了打出杨辉三角的代码部分。
等下,这题目不是还有个范围吗?好的,这就是此文要讲述的自顶向下,逐步求精的方法。
刚才所列的是杨辉三角打印的原理代码部分,虽然看似已经解决了这个题目,但不要忘了,这仅仅只是题目的一部分,距离真正完成还是差了并不止一点哦。
回观题目,【不在范围内的n输出“Out Of Range.\n”】,这一句,是与代码平行乃至更强的条件限制部分,因此在完成该任务的开始,就应分好层次,若n不在这个范围,就直接跳出而打印“Out Of Range.\n”咯。(跳槽一下:反正也就那么几个不同的数,实在想不到规律的还不如直接打表哈哈!!!)
至此,任务完成咯。
例2:洗衣机
洗衣机作为日常生活中极其重要的电器,其操作定然是便于人们使用的,而如何使得人们操作它而感到方便舒适,则是程序设计者的任务!
若使用之前所述的“自顶向下,逐步求精”的方法,首先要做的,便是分析洗衣机所具有的功能,然后是这些功能操作所需要的过程,然后我们在分别对此以程序!
正常而言,一个洗衣机程序,不可缺少的必然有进水,洗涤(漂洗),排水,脱水等程序。
而将它们分别用代码实现,则又需要思考设计它们分别的实现方式,比如说,脱水的时间、进水的时间或量、以及洗涤时洗衣机滚轴的转动方式等等。而思考到这一层之后,接下来进行的便是使用最简单使实用的代码使之实现!!伪代码如下:
READ 用户选择模式 REPEAT 注水 UNTILL 水位=注水要求 REPEAT 浸泡 UNTILL 时间 = 时间要求 WHILE(电机启动时间>0) { REPEAT 电机左转3次 电机右转3次 时间-1单位 } ENDWHILE WHILE(水位!=0) 排水 ENDWHILE FOR(脱水时间>0) 电机转动 脱水时间-1单位 ENDFOR 关闭电源
而设计完这些最基本的步骤,还需要的便是思考功能,比如说:快洗与普通洗的区别,再附以代码来实现之后组装在一次就完成此项目咯。
结
本次对于程序设计方法原理的学习让我对未来软件设计充满了希望,毕竟,一般而言,同等条件下,一个有方法的人总比没有的要出色,是吧?相关文章推荐
- 深入“自顶向下,逐步求精”——面向过程程序设计方法
- 深入“自顶向下,逐步求精”——面向过程程序设计方法
- 深入“自顶向下,逐步求精”——面向过程程序设计方法
- “自顶向下,逐步求精”——面向过程程序设计方法
- 【实践+科普】自顶向下,逐步求精——面向过程程序设计方法
- 自顶向下,逐步求精:从洗衣机工作程序看面向过程程序设计方法
- 程序设计中自顶向下,逐步求精的方法
- 自顶向下逐步求精的程序设计方法
- “自顶向下, 逐步求精”的程序设计方法。
- 简述“自顶向下,逐步求精”的方法
- “自顶向下, 逐步求精”的程序设计方法。
- “自顶向下,逐步求精”——面向程序设计
- 简析“自顶向下,逐步求精”的程序设计方法
- 分治法--“自顶向下,逐步求精”的程序设计方法
- 自顶向下,逐步求精(Top-down)的程序设计方法简介
- 自顶向下,逐步求精的程序设计方法
- 自顶向下,逐步求精的程序设计方法。
- “自顶向下, 逐步求精”的程序设计方法
- “自顶向下,逐步求精“的程序设计方法
- “自顶向下, 逐步求精”的程序设计方法。