2.11 上一节见识了一下神医扁鹊兄弟三人的胖瘦,现在,我们再来看看西方一位以作恶而昭著的人物——它就是撒旦。本回的目的是说明,看问题要把握其实质,抓住这一点,问题就好解了。抓实质是可以学到的。
图:撒旦虚心听取玩变脸败因
撒旦(Satan),西方神话宗教人物,上帝和人类邪恶的敌人,通常被认为是堕落天使的领袖,不折不扣的恶魔,他有一个最好的把戏,是在不同人的面前可以显现不同的面目——变脸。令撒旦想不明白的是,耶稣怎么会有那么多跟随者呢?
有一天,耶稣带领众信徒上山传教,撒旦也决定去看个究竟。第一天,他对徒弟们说,是我的徒弟的,你们一人捡两块石头,跟我一起走。于是,徒弟们一人拿起两块石头,向山上走去。撒旦心想,大的太重,于是捡了两块最小的石头。到了山上,耶稣依次看,轮到撒旦了,拿到手中一块大的,然后说:你是撒旦吧。撒旦很纳闷,心想,一定是石头拿的太小了,露馅了,灰溜溜地走了。 第二天,耶稣依然带领他们上山,并且照旧让他们每人捡两块石头。撒旦变了另外一张脸,心想,昨天我捡了两块最小的,今天我要捡两块最大的。到了山上。耶稣还是轮着看,走到撒旦面前时,拿了块大的,又笑着说:你是撒旦。撒旦又灰溜溜地走了。第三天,上山时,耶稣又让他的徒弟们捡两块石头。撒旦变了脸,心想:第一天我捡了两块最小的,第二天捡了两块最大的,都露了馅。今天我捡一大一小,不就万无一失了吗?于是他捡了一大一小两块石头上了山。到了山上,耶稣还是轮着看,走到撒旦面前时,又挑了块大的接下来,耶稣还是笑着说:你是撒旦!撒旦弄不明白的第二个问题是,耶稣怎么老将我认出的呢?耶稣又笑着说,你的变脸游戏挺不错的,不过我给提点建议,在做之前,穿上鞋子,你是六指呀!撒旦当时昏倒在地!
我们的问题是:耶稣接过的三块石头,请按从大到小排一下?
第一步:三积木 这是最简陋一个图形,也是最基本的一步,“目”形图,我们略去,从第二步开始。
第二步:做头尾
上面的三部分,先分析开头和结尾部分,开头是什么呢?题中的已知条件,是三块石头重量,我们用a,b,c来表示。目标是什么呢?是从大到小的三个数,怎样表达呢?第一种方式是象上节的扁鹊石头一样,输出还是用a,b,c,但这三个a,b,c和输入的不尽一样,输入的值有六种可能,而输出只有一种(如图1B);第二种方式是直接输出这六种方案中的一种(如图1A)。
图2B 图2A
第三步:连头尾
如何将开头和结尾连接起来呢?我们也出现上面的两种思路,第一种,我们可以继续按照上节的做法,一步步下去,除了找到最大的,还要找出中间的,因为是三个数,所以最小的也就有了。怎样才是真正的最大值,将这个过程分析一下,可以分成两步,第一步,将a,b比较,使a>b;第二步,将a和c比较,使a>c,通过此两步比较完成,a的值一定就最大了,如图2B中间所示。还有是如何确定第二大的,这个问题只要一步就可解决,比较b,c,使b>c。所以该问题经过三步可解决。
第二种思路该如何解决呢?
输出“六种方案中的一种”,当然要用分支结构,但一个分支又只能解决二选一的问题,怎么办呢?可以将这六种方案合成两大类,后面可以再将合并的分开,问题就得到了解决(如图2A示)。每一个分支中又包含了三种情况,所以还要将各自的三种情况再合并成两种,通过分支解决,即分成二选一的情况和一种的情况,在二选一的情况中还要再用一个分支,由此我们可以看出,分支和分支嵌套了三层之多!(如图3所示),三层中的逻辑关系,请大家可要仔细看好了。
图3B 图3A
第四步:贴语法
下面我们还用QBASIC语言来解这个题目。第三步图中的各个语句和具体语言的语法还有一定的差距,根据相应语言,主要体现在输入和输出语句中,还要再行将相应语句转化。
第五步:写代码
下面可以写代码了,两个程序中,第一种方法的代码较简单,第二种的代码比较难写,但如果我们遵循下面的原则,也就比较简单了,先整体分块,然后从整体到部分。
第一种方法(如图3B示),整个图分成了五大部分,复杂一点是的中间的三部分,第一部分和最后一部分最简单,写的过程中要注意代码的开始和结束标志。第一种代码如下:
input a,b,c
if a>b then
else
d=a
a=b
b=c
endif
if a>c then
else
d=a
a=c
c=d
endif
if b>c then
else
d=b
b=c
c=d
endif
print a,b,c
第二种方法(如图3A示)整个图可分成两大部分,下面的分支们做为一部分,这部分比较复杂,上面的一部分原封不动照搬,非常简单。写完这一部分后,要注意先将下面的分支的框架形式写好,然后通过填空的形式向上填,这样就不容易出错了,后面还要注意使用代码里嵌风格,这样更容易分清代码和代码的关系。代码如下:所以代码如下:
input a,b,c
‘第一层分支
if a>b then
if c>a then
print c,b,a
else
if c>b then
print a,c,b
else
print a,b,c
end if
end if
else
if c>b then
print c,b,a
else
if c>a then
print b, c, a
else
print b, a,c
end if
end if
endif
(上程序在Qbasic下调试通过)
程序演义到现在,由于分支结构的出现,解决的问题呈现出多姿多彩的形式,不管怎么变,分支只有两种形式,上下罗在一起形成一种顺序关系,或嵌套在形成连环分支套加式,但不管怎样,都是为解决更多种情况而存在的。
在我们将本题同两个数排序的孔融的梨子比较一下,会有许多精彩的东西出现。一个最简单,两个稍复杂,三个更复杂,那面对一万个呢?有意思的问题可能正在这里,“3”是个有意思的数字,可能会因之而搔头,也可能会因之而慨叹!
阿兰告诉大家的是:在编程方面,撒旦脸蛋的变化告诉我们的更重要的是,要抓住本质,也要学会找出规律,办法总比困难多,笑着去面对,“上帝”也是这么想的。
后面我们还将奉献上这样一些有意思的题目,进一步来看一下分支结构的特点,以迎接更复杂的分支问题的挑战。欲知后事如何,且听下节分解。
用本节介绍的方法,能求出三个数中的最大值吗?如何求?
小测验参考答案: 一种最简单的办法是,将六条输出语句的后两个变量的名称去掉,只保留一个;如果您不怕麻烦,还可以通过三个分支语句嵌套的形式来完成。