高斯课堂巴掌助兴——阿兰用心二解循环

编程爱好者

高斯(Gauss)是德国的数学家、天文学家和物理学家,被誉为历史上伟大的数学家之一,和阿基米德、牛顿并列,同享盛名。高斯的成就遍及数学的各个领域,他十分注重数学的应用,并且在对天文学、大地测量学和磁学的研究中也运用了大量数学方法。

高斯十岁时,解出了那道著名的"从一加到一百"问题,他也一下子树立了在老师心中的地位。但顽皮是孩子的天性,当老师还没到达课堂时,孩子们就做起游戏来,玩得兴起时,大家相互拍起了巴掌。到老师到来时,他们还没有停止游戏,把老师气火了,为了以示惩戒,老师给学生们出了一道题,谁做不出来,中午头就不准回家吃饭!题目如下:

40个同学,相聚在一堂,相互击一掌,总计多少响?正沉浸在巴掌声中的小朋友们一下子给难住了。小高斯动动脑,又第一个解了出来!我们的问题是:用电脑程序,我们如何计算出究竟多少响?而和上面问题对应的还有第二个问题:一班小同学,相聚在一堂,相互击一掌,总计780响,问有多少个同学相聚在一堂?

高斯巴掌问题解析

第一问题分析:

下面先看第一个问题,高斯课堂的巴掌声,如何求出呢?我们不妨从1开始,列出一个序列:

人数 响数

1 0

2 1

3 1+2

4 1+2+3

40 1+2+3+…+39

规律是什么呢?实质上和高斯求1-100的和差不多,是求1-39的和。这是一个非常规律化的问题,要不然高斯就求不出来了,用高斯求1-100的方法,值很简单地就算出来了:(1+39)×39/2=780。用电脑如何求呢?首先,我们需要思考一下上述规律:

s1=0

s2=1

s3=s2+2

s4=s3+3

s40=s39+39

上面的代码中像隐藏了什么东西,将下标去除后,一个美妙的规律又出现了:

s=0

s=1

s=s+2

s=s+3

s=s+39

细看一下,这正是个美妙的循环呢(如图1所示)。

25-f18-2.jpg
图1

将第二句也加入规律中,但要保持变形等价,可以再加上一个值为0的s,即s=1变成s=s+1,因为语句右边的s为0,所以两句实现的实际作用相同。这一句可以放入后面的循环中,循环就是从1到39了(如图2所示)。

25-f18-3.jpg
图2

源代码也就有了:

s=0

for i=1 to 39

s=s+i

next i

print s

第二问题分析:

再看第二个问题:第二个问题和第一个问题不同,但求解方法却是一样的,第一个问题是求1+2+…+39的和,而第二个问题是求1+2+…+?=780,求的是人数。

因为我们知晓规律是什么,虽不能准确地判断究竟是多少同学在班上,但范围是能肯定的,因为高斯帮我们求过,1-100的和是5050,所以不是1人,也不是101人,但一定在1-101之间,下面,我们就选择这个范围,将符合条件的那个数输出来,程序在上面程序的基础上,在循环体内加上一个分支进行判断,也就行了。

s = 0

For i = 1 To 100

s = s + i

If s = 780 Then

Print i + 1

End If

Next i

上面的程序有什么缺点吗?第二个示例的答案我们知晓,也应该是40人,所以会出现从41人到101人做的都是无用功。怎样才能改善呢?有没有一种语句可以正好达到这个点,然后就停止工作呢?有!

我们可以先模仿规律。怎样将规律模仿出来呢?自然我们可以从1个人的情况一直向下寻找,但向下找不可能是无限制的,需要有一个截止的条件,这就是780响。所以它的处理过程也是个循环,循环执行多少次我们不知道,但只要数量满足780响了,一切OK,我们就找到了那个和780响对应的数值了。

所以我们遇到一种和我们前面所用的完全不同的一种循环,循环的次数在编程时是不确定的(如图3所示)。

25-f18-4.jpg
图3

代码如下:

s = 0

i = 0

While s < 780

s = s + i

i = i + 1

Wend

Print i '输出

两问题对比

两种循环,都是为了方便我们解决问题。关于循环,像我们从顺序的状态向循环转化时一样,要注意其必需的三个条件:首先是,问题有超过三个以上的相似性,如果太少,循环的方便性就显现不出来了。我们遇到的几个问题,大都情况多于三个,本题中更是达到40个,这么多的情况,自然首先想到要用循环。

其次是,循环的开始和结束要能够控制,特别注意第二种情况,如果不能控制,将会出现循环永远执行的状况,造成的直接后果就是死机!从这一点上说,两种循环的形式是可以转化的,如果把第一问转成第二种循环形式,代码如下:

s = 0

i = 1

While i <= 39

s = s + i

i = i + 1

Wend

Print s

它有"形似神不似"的效果,赋值语句的精彩正在于此,在潘多拉豆一回中我们有过介绍。正是赋值表面的相似,使得我们做循环时能更简洁地找出那块重复的东西,但它做的实际工作却一点都不含糊,还是那么多!

阿兰开讲

现实问题的分析过程,越析到最后,越可能富有戏剧性,除了大问题是由小的基本问题组成的外,努力透过文字的描述去发现事物的真相,有时显得尤其重要,怎么办呢?动手,写下来,从最简单的情况入手,画出来,然后动脑找出其中蕴藏的东西。

循环是我们破解现实问题的有力工具。循环有三个特点:第一,超过三个以上的相似性,正因为相似,所以用一种对于人类来说简洁的方法,将我们的简单劳动解放出来;第二,循环次数是有限的,或者说应该努力分清其开始和结束的条件;第三,形似神不似的传达者,赋值或赋值的形式!将这三个特点把握了,循环的本质问题就搞清了。

此外,循环语句主要有两大类:一种是循环次数确定,也就是中间部分该执行多少次,在编程的时候我们是知道的;另一种是循环次数不定的循环,或者也可以说循环多少次和我们所求的解有直接关系。只要针对实际问题应用好两大类循环,再复杂的问题都会迎刃而解了。