那,接下来一个问题。 那是不是有了这个解决方案,我就有程序了啊?
啊,这是不是很容易就做成的一件事情啊?当然不是。
对一个问题而言,想到了解决方案,只是完成了第一步。
有了这个解决方案以后啊,还必须把这解决方案描述成程序。
这是一个两步走的过程。前一步呢,重在实考。
那后一步呢,重在描述。
这是两个不同的步骤。
但有些同学说,哎呀,描述,那容易。那,是不是描述问题就不用再实考了啊?
在这,我想告诉大家,其实啊,像要描述一个问题,是一件不容易的事情。
那,比方说啊,MIT在筛选博士生的时候啊,曾经出过这样一道题目。
啊,请你写一段文字,向一个5岁的小男孩描述一下
如何系鞋带。可见,他们对描述是非常非常的重视。
而且呢,这个描述一个问题其实是一件非常有难度的事情。那么,
当你已经拥有一个解决方案的时候,你怎么样
才能把这个解决方案描述为计算机能够理解的程序呢?
其实啊,这才是我们在这个课上重点要讨论的问题。
当然,把一个解决方案描述成程序啊,
有很多的办法。那么,我们现在所学的,是利用一个
结构化程序设计语言来描述这个解决方案。
那么也就是说,我们应该按照结构化
程序设计的思想来描述这个解决方案,当然应该是这么去做。
但是在现阶段,因为我们是感兴认识的阶段,我先不去探讨这个结构化程序设计的
一些深奥的道理,我们先从感兴的层面给大家一些提示。
所以啊,在这里,我写了这样一段话。在结构化程序设计中啊,
总是按照先粗后细,先抽象后具体的
这样一种方式。对所要描述的解决方案,进行穷尽式的
分解,穷尽到什么程度呢?直到能够使用顺序,分支,循环,
这三种结构来描述你的解决方案。那,什么叫做先粗后细,先抽象后具体啊?
为了让大家有个感兴的认识,我呢,在这个做一个类比。 看这幅图。
那这幅图里头呢,包含了6幅小的图象。这6幅图画
其实描述了一个绘画的过程。你看第一幅图画。
第一幅图画里头,它是先用很粗的线条去勾了出来要画哪些东西。
那这个画大致的结构会是什么? 它先不去管那些细节,然后在后来的过程里头
慢慢的再去增加细节。啊,对局部进行处理。
那,你看,这个体现了一个一样的过程。 先抽象再具体,先粗线条再
考虑细节,啊,一步一步的完成。我们再看一幅。
对这幅画更是如此。我们要画一幅图像,
我们先用粗线条勾了出来大致的轮廓,
啊,它的结构是什么。然后呢,对每个部分再进行不断的细化,不断的细化,
一步一步地完成整幅画。
那,这是在绘画的领域。其实啊,在自然语言这样的写作里头也有这样的规律。
啊,比方说Babara Minto,就曾经啊,提出了一个金字塔原理。
那,Baraba Minto 曾经在McKinsey工作过。她呢,写的报告非常的出色。
后来她写了一本书,提出了一个广为人知的写作方面的道理。
那就是如何去构建一个文章的结构。她把这个道理呢,称为金字塔原理。
在金字塔原理里头啊,她也提出了建立一个文章的金字塔结构。
那么你想像别人清楚地表达一个问题的时候啊,那你说缩写的那个文章
应该符合一个金字塔的结构,那就是说由种到分,由粗到细,
这样呢,才更便于被别人所理解。
那么在这啊,我不想讨论艺术和科学之间的相同与不同,
也不想讨论中西方绘画之间存在的一些差异。有些同学可能在思考这些问题了啊,
我不想讨论这些。我只想告诉大家,你看,由粗到细,由抽象到具体,
这样来描述一个问题,它符合人们描述事物的规律。
啊,对绘画是如此,对写作是如此,对编程序
也是如此。那,回到刚才的我们这个问题,
你看,我们已经找到了一个解决方案。
那么,该如何把这个解决方案描述为一个程序呢?
嗯,在这啊,按照刚才我们告诉大家的规律,
先不要考虑那些编程序的细节。不要一上来就定义变量,
有时候我在上课的时候啊,提问问题,比如说谈论某个问题的时候,我就问一个同学。
我说,你是怎么解决的啊?有些同学站起来就开始说,啊,现定义了变量,后呢给变量附值,然后呢,For循环,
从0,嗒嗒嗒嗒嗒。他俨然背他心里的程序啊。虽然我非常佩服他的记忆力和这个
出口出程序的这种能力,啊,但是,我仍然不能够同意他的这种做法。
因为对于小的问题,你可以直接说出一个程序来,那对于大的问题呢?
难道你也从第一行程序开始,用程序来描述你的解决方案?退万不讲,你真的是这样的天才,
你也许可以这样去做,但未必别人能听得明白啊。
如果只有你明白,而无法跟别人进行交流, 那你就没办法进行团队协作了啊。
嗯,再说了,如果你真的是天才,我们也不用来讨论这些方法了,你可以直接去写程序了。
嗯,所以说在这啊,我们先要去描述我们要写的这个程序的轮廓。
啊,大致的轮廓。
用最简单的方式去想象这个轮廓。甚至去勾画这个轮廓。
你可以把这个轮廓给它画出来。那,比方说,我就画出了这样的一个轮廓。
你看,那,这样的轮廓啊,它不是用来给计算机看的。 它只是用来帮助自己或者别人理解我要怎样去
写这个程序的。当然你也可以不用这种方式,而用你自己的方式,
也不一定是图,也可以用文字。啊,怎么样都可以。我想要你做的就是
一定要在脑子里面形成一个轮廓,一个结构,嗯,
你要写的程序,它就长成这样,啊,你心里非常非常的有数。
因为对这样一个问题而言,我已经知道怎么去解决这个问题了。
那,怎么把它写成程序啊?我就可以这样来画。你看,输入刀数N,
然后呢,先设置好初数值,第1刀的时候两块, 啊,有的同学从0开始,也可以啊,0刀的时候,是一大块,
嗯,1块。然后接下来就是一个累加,
啊,这个累加就是一个循环,那这个循环,怎么去做的,细节,我先不去想。
啊,然后呢,我就把这个块数输出出来。你看这个程序的结构,先由一个输入,
再有个初数值的设定,然后一大块循环,循环里面而解决累加的问题。
循环完了之后输出一个块数。程序的结构如非如此。
我希望你在写程序之前,就能够形成这样的一个轮廓。
在你的心里有这样一个结构存在, 在去动手写程序,你就汹涌成除了。
那我们来看一下这个,这个例子的程序是不是这样的。你看这个程序的结构是不是这样的。
先输入一个数据,把这个N输入进来,然后呢,输入一个 初数值,然后呢,有一个循环,啊,这个循环不断的去进行。
啊,反正在循环里头完成累加。最后呢,有一个输出。
啊,把这个块数输出出来。
是不是这样一个结构啊?所以说,在你写程序之前啊,你心里头就有这样一个结构
存在。我要先输入,然后再输入一个初数值,然后呢是一个循环,
最后呢,有一个输出。那,如果有这个结构的话,你在写程序
非常非常的顺利。你要有这样一个,
有这样一个概念。先让自己形成这样的认识,
再去动手写程序。那么,写程序完全是可以不从变量定义先开始的。
你可以先把这个主干想办法给它描述出来。
然后呢,缺什么变量,再回头定义什么变量。
甚至于在这个过程中,可能有些许的语法错误,啊,也没关系。
你可以边写边改,也可以先把整个程序 写得差不多,然后再来调试,再来Debug。
这就是写程序的基本的一个过程。Ok,那么,
通过了这个例子,我们还学了不少的东西。我们就来总结一下,看我们学到了些什么。
首先,我们可以知道啊,写程序是这样一个过程,当你面临一个问题的时候,啊,比方说,一道题目,
你必须要先找到一个相应的解决方案。
先去思考这个解决方案,然后呢,再想办法把这个解决方案变成程序。
那么,其实写程序是一个这样的过程,对吧。
因此呢,如果面对一个问题的时候,你还没有想好解决方案,
千万不要急着就去动手写程序。危害我已经讲过了。
这是第1点。第2点,有了解决方案以后,怎么写成程序呢?
可以按照先粗后细,先抽象再具体的这个办法。
先建立起这个程序的轮廓。 当然在这个过程里头啊,如果有必要的话,你可以借助一些
建模工具。啊,所谓建模工具,就是一些用来画图的工具。
在软件建模领域里头啊,有很多类似的这样的工具。
那么我在北大呢,还讲出了一些研究生的课程。那么,跟这个部分是有点关系的。
如何去建模这个软件。当然呢,那个是主要面对内向方面的。 那么,用那些工具呢,可以帮助你来画一些图。
嗯,有了这些图后啊,然后再动手写程序。其实这过程,它的目的
仍然是帮助你先建立一个程序的基本的轮廓,
基本的结构,啊,然后再动手去写程序。
第3点,在写程序的过程中啊,可以先写出程序的轮廓,
而不是从定义变量开始的。 可,呃,不是先去定义各种的变量,
啊,可以先写出程序的轮廓。那么写出这个轮廓以后再回头来
补上所需要的定量的定义。嗯,这样去写程序。
可以保证让我们既有效率,又能够写出正确的程序来。