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


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

    先来讲评一下“陶陶摘苹果”这个问题。该题源于: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为基础发展起来的。不过,这又是另一个故事了……

  • 相关阅读:
    Nodejs 进阶:Express 常用中间件 body-parser 实现解析
    Nodejs进阶:express+session实现简易身份认证
    Node 进阶:express 默认日志组件 morgan 从入门使用到源码剖析
    Nodejs进阶:如何玩转子进程(child_process)
    express+session实现简易身份认证
    你真的了解UIViewController生命周期吗?
    你真的了解UIGestureRecognizer吗?
    你真的了解UIEvent、UITouch吗?
    你真的了解UIScrollView吗?
    你真的了解UITextView吗?
  • 原文地址:https://www.cnblogs.com/fzd19zx/p/1965972.html
Copyright © 2020-2023  润新知