C,是一种信仰

代码点评及解析:陶陶摘苹果

目的:利用这篇文章,向程序设计的初学者,介绍一下“如何利用计算机解决实际问题”这个听起来好大好大的问题。

先来讲评一下“陶陶摘苹果”这个问题。该题源于:2005年NOIP复赛普及组第一题。具体如下:

【问题描述】
陶陶家的院子里有一棵苹果树,每到秋天树上就会结出10个苹果。苹果成熟的时候,陶陶就会跑去摘苹果。陶陶有个30厘米高的板凳,当她不能直接用手摘到苹果的时候,就会踩到板凳上再试试。
现在已知10个苹果到地面的高度,以及陶陶把手伸直的时候能够达到的最大高度,请帮陶陶算一下她能够摘到的苹果的数目。假设她碰到苹果,苹果就会掉下来。
【输入文件】
输入文件apple.in包括两行数据。第一行包含10个100到200之间(包括100和200)的整数(以厘米为单位)分别表示10个苹果到地面的高度,两个相邻的整数之间用一个空格隔开。第二行只包括一个100到120之间(包含100和120)的整数(以厘米为单位),表示陶陶把手伸直的时候能够达到的最大高度。
【输出文件】
输出文件apple.out包括一行,这一行只包含一个整数,表示陶陶能够摘到的苹果的数目。
【样例输入】
100 200 150 140 129 134 167 198 200 111
110
【样例输出】
5

这个问题,不是很困难的。但是,对于还没有学习过“数组”概念的初学者来说,恐怕就只能用“输入输出重定向”的方法来读取并且解决问题了。我先来谈谈这个方法:

【解题思路】
利用输入输出重定向。
不使用数组存储技术,解决本题。
1、读入陶陶把手伸直的时候能够达到的最大高度(taoHeight)。
2、重新重定向输入文件
3、读入每个苹果的高度,并计数(counts)能摘得到的苹果。

我们注意到,在这种解法中,需要2次利用输入重定向功能,目的是为了分别读入“陶陶把手伸直的时候能够达到的最大高度(taoHeight)”和“每个苹果的高度”。

源代码如下:apple.c

0001 # include "stdio.h"
0002 
0003 # define APPLES_AMOUNT (10)        /*苹果的个数*/
0004 # define HEIGHT_OF_CHAIR (30)    /*椅子高30厘米*/
0005 
0006 int main() {
0007     int taoHeight,        /*陶陶把手伸直的时候能够达到的最大高度(厘米)*/
0008         appleHeight,    /*苹果的高度*/
0009         counts,            /*陶陶能摘到的苹果*/
0010         i;
0011     /*读入陶陶把手伸直的时候能够达到的最大高度(taoHeight)*/
0012     freopen("apple.in","r",stdin);
0013     /*跳过输入文件开头的APPLES_AMOUNT个数据(苹果高度)*/
0014     for (i=1; i<=APPLES_AMOUNT; i=i+1) scanf("%d",&appleHeight);
0015     /*读入陶陶把手伸直的时候能够达到的最大高度(厘米)*/
0016     scanf("%d",&taoHeight);
0017 
0018     /*重新重定向输入文件*/
0019     freopen("apple.in","r",stdin);
0020 
0021     /*读入苹果的高度,并计数(counts)能摘得到的苹果。*/
0022     counts=0;
0023     for (i=1; i<=APPLES_AMOUNT; i=i+1) {
0024         scanf("%d",&appleHeight);
0025         if (appleHeight<=(taoHeight+HEIGHT_OF_CHAIR)) counts=counts+1;
0026     }
0027 
0028     /*重定向输出文件*/
0029     freopen("apple.out","w",stdout);
0030     printf("%d",counts);
0031 
0032     return 0;
0033 }

另一方面,对于学过了“数组”概念的学生,自然可以考虑利用数组来解决本题了:

【另一种解题思路】:利用数组存储。
利用数组存储苹果的高度。
1、把苹果的高度读入数组apples(存储每个苹果的高度)
2、读入陶陶把手伸直的时候能够达到的最大高度(taoHeight)
3、扫描数组apples,计数(counts)能摘得到的苹果。

在这里,我们只需要读入1次输入文件(apple.in)即可。源代码如下:

0001 # include "stdio.h"
0002 
0003 # define APPLES_AMOUNT (10)        /*苹果的个数*/
0004 # define HEIGHT_OF_CHAIR (30)    /*椅子高30厘米*/
0005 
0006 int main() {
0007     int taoHeight,        /*陶陶把手伸直的时候能够达到的最大高度(厘米)*/
0008         apples[APPLES_AMOUNT],    /*苹果的高度*/
0009         counts,            /*陶陶能摘到的苹果*/
0010         i;
0011     /*读入陶陶把手伸直的时候能够达到的最大高度(taoHeight)*/
0012     freopen("apple.in","r",stdin);
0013     /*把苹果的高度读入数组apples(存储每个苹果的高度)*/
0014     for (i=0; i<=APPLES_AMOUNT-1; i=i+1) scanf("%d",&apples[i]);
0015     /*读入陶陶把手伸直的时候能够达到的最大高度(厘米)*/
0016     scanf("%d",&taoHeight);
0017 
0018     /*描数组apples,计数(counts)能摘得到的苹果。*/
0019     counts=0;
0020     for (i=0; i<=APPLES_AMOUNT-1; i=i+1) {
0021         if (apples[i]<=(taoHeight+HEIGHT_OF_CHAIR)) counts=counts+1;
0022     }
0023 
0024     /*重定向输出文件*/
0025     freopen("apple.out","w",stdout);
0026     printf("%d",counts);
0027 
0028     return 0;
0029 }

上述代码,都可以达到解题的目的。

解题的源代码及测试的数据文件,可以从这里下载到:http://cid-bfe8af46e42e3ecf.office.live.com/self.aspx/%e7%ae%97%e6%b3%95%e7%ab%9e%e8%b5%9b/%e6%ba%90%e4%bb%a3%e7%a0%81/%e7%ae%97%e6%b3%95%e7%ab%9e%e8%b5%9b%e7%bb%83%e4%b9%a04%ef%bc%8c%e6%ba%90%e4%bb%a3%e7%a0%81.rar

下面是我想说的一点感想:

利用电脑解决实际问题,常常面临的问题是:电脑的信息表达与现实世界的信息现实,存在着巨大的差异。行话来说,“现实世界的信息现实”被称为“现实域”;而“电脑的信息表达”也被称为“问题域”。上述差异,被称为“现实域与问题域之间的差异”。
这句话的意思是:现实中,陶陶是个活蹦乱跳的小朋友,苹果是红扑扑地长在树上的水果。但这些信息,对于电脑解决问题,是没什么帮助的。所以,我们要通过所谓的“抽象”,把我们所感兴趣的信息,比如:椅子的高度、陶陶的高度、苹果的高度,在电脑中进行表达。通过抽象,我们就可以缩短“现实”与“电脑”在表述问题上的差异。比如,我们用整数来存储椅子的高度、陶陶的高度、苹果的高度,就是对“椅子”、“陶陶”和“苹果”的抽象,排除了与解题无关的多余信息。这种抽象,看似简单(因为本题确实不难),但随着问题难度的增加,会变得非常的复杂。最终,“对现实世界的抽象”演变成了计算机程序设计的一门重要技能:数据结构

再一个问题,我想讲的是“对数据的处理”。假使我们已经“成功地对现实信息进行了抽象”,如上所述,形成了几个整数。那么该如何处理这些整数呢?由上所述,你会发现,同样是为了解决问题,我们可以采用2种不同的方法:多次输入重定向处理数据、或是利用数组存储并处理数据。也就是说,由于“数据存储形式的不同”(利用数组存储,或是不用数组存储),我们处理数据的方式也会变得不同。这种“处理数据的方式”,就是所谓的“算法”。用行话来说,“算法”是针对特定的“数据结构”进行数据处理的

所以,N·沃斯先生(Pascal语言的发明者)才会说出那句非常有名的话:“算法+数据结构=程序”。事实上,这是一本书的名字《算法+数据结构=程序》,它是N·沃斯先生所写的一本用Pascal语言介绍算法和数据结构的一本经典巨作。其中,N·沃斯先生不但详细介绍了Pascal语言的用法,而且针对排序问题,详细讨论了各种算法的性能比较。《算法+数据结构=程序》是一本能和《C程序设计语言》相媲美的经典著作,绝对值得每一位决定深入学习程序设计的人买下来反反复复地阅读。可惜,《算法+数据结构=程序》这本书市面上根本就没有再版了。我所看到的这本书,是十几年前,在福建省图书馆里翻到的(整个书皮都是撕破了再粘上去的),科学出版社198?年翻译出版的,兄弟我仔仔细细精读了2遍,感觉受益匪浅。

至于,Pascal语言,如同C语言一样,也有了长足的发展。Delphi所用的Object Pascal,就是以Pascal为基础发展起来的。不过,这又是另一个故事了……

posted @ 2011-02-26 21:39  胖乎乎的王老师  Views(3872)  Comments(0Edit  收藏  举报
Email 联系我:fzd19zx@qq.com