当前位置:   article > 正文

基础算法(算法——程序的灵魂)_算法是程序的灵魂,可以使用什么

算法是程序的灵魂,可以使用什么

本篇由C语言表示算法

程序=算法+数据结构

一个程序主要包括两方面:

1. 对数据的描述。在程序中要指定用到的数据及这些数据的类型和数据组织形式,这就是数据结构(data structure)。

2. 对操作的描述。要求计算机进行操作的步骤,即算法(algorithm)。

        数据是操作的对象,操作的目的是对数据进行加工处理,以得到期望的结果。在设计一个程序时要综合运用算法、数据结构、程序设计和语言工具四个方面的知识。算法是程序的“灵魂”,数据结构是加工对象,语言是工具,编程需要采用合适的方法。

什么是算法

        为了解决一个问题而采取的方法和步骤,就称为“算法”。程序中的操作语句就是算法的体现。

        方法有优劣之分,一般都希望采用方法简单、运算步骤少的方法。因此,为了有效的解决问题,不仅要保证算法正确,还要考虑算法质量,选择合适的算法。

        计算计算算法可分为两大类:

        数值运算算法,目的是求数值解,此算法往往有现成的模型,可以运用数值分析方法,因对数值运算的算法的研究比较深入,算法比较成熟。

        非数值运算算法,涉及面十分广泛,且种类繁多、要求各异,难以做到全有模型参考,因此只有一些经典的非数值运算算法有现成的、成熟的算法可供参考。许多问题往往需要使用者参考已有的类似的算法思路,重新设计解决特定问题的专门算法。

简单算法举例

解题步骤为算法思路

求1×2×3×4×5

设置两个变量x,y。x代表被乘数,y代表乘数。将每一次相乘的积放入被乘数变量x中。

1. 令 x=1,或写为1=>x   (表示将1存放到变量x中)

2. 令 y=2,或写为2=>y   (表示将2存放到变量y中)

3.  x*y=>x (使x,y相乘,乘积仍放在变量x中)

4.  y+1=>y (使y的值加1)

5.  如果y小于等于5,就返回执行 3. 及其后面的步骤(如条件符合一直重复此步骤);否则算法结束。最后x的值就是5!的值。

PS:如果要得到1、3、5、7、9、11的乘积我们只需将上面步骤略作修改就行。将y=2改为y=3,y+1=>y改为y+2=>y,并限制y小于等于11即可。

在50个学生中,输出成绩在80分之上的学号和成绩

用X代表学生学号,下标i代表第几个学生,X1代表第一个学生学号,Xi代表第i个学生学号,Y代表学生成绩,Y1代表第一个学生成绩,Yi代表第i个学生成绩。

1. 令  1=>i

2. 若Yi>=80则输出Xi和Yi,否则不输出。

3. i+1=>i

4. 若i<=50则返回执行 2.  及其后面的步骤(如条件符合一直重复此步骤);否则算法结束。

PS:变量i代表下标,先令其为1,检查Y1的成绩,然后使i增值为1,一次检查Yi的成绩。

判定2000-2500年中的每一年是否为闰年

闰年的判定条件:能被4整除但不能被100整除,能被400整除。

设置year为被检测的年份

1. 2000=>year

2. 若year不能被4整除,则输出year的值和“不是闰年”,转到 6. 继续执行程序。

3. 若year能被4整除不能被100整除,则输出year值和“是闰年”,转到 6. 继续执行程序。

4. 若year能被4、100整除,还能被400整除,则输出year值和“是闰年”,转到 6. 继续执行程序。

5. 输出year的值和“不是闰年”

6. year+1=>year

7.当year<=2500时,转到 2. 继续执行,否则停止。

求1-1/2+1/3-1/4+...+1/99-1/100的值

sign代表当前处理项前的数值符号,term代表当前项的值,sum代表当前各项的累加和,deno是当前项的分母。

1. sign=1                            //预先设置sign为1(再此程序中sign为1代表加号,-1代表减号)

2. sum=1                            //设sum为1,等同于将第一项加到了sum中,后面因从第二项开始累加

3. deno=2                           //deno为分母的值,第二项分母为2

4. sign=(-1)*sign                //通过乘以(-1)将sign的值在1与-1中转换

5. term=sign*(1/deno)        //term代表当前项的值,deno是分母,sign代表与运算符号

6. sum=sum+term              //进行累加操作

7. deno=deno+1                //使分母值+1

8. 若deno<=100,返回 4. 继续执行,否者算法结束。

给出一个大于或等于3的正整数,判定是否为素数

素数的判定条件:除了1和该数本身外,不能被其他任何整数整除的数。

设定被除数x,除数y

1. 输入x的值

2. y=2

3. x被y除,得到余数z

4. 若z=0,代表x能被y整除,则输出x的值和“不是素数”,算法结束

5. y+1=>y

6. 如果y<=x-1,返回从 3. 开始执行;否则输出x的值和“是素数”,然后结束。

PS:其实被除数只需被2到根号被除数之间的整数整除就可判断是否是素数,即y<=根号x。

算法特性

1. 有穷性。

        一个算法应包含有限的操作步骤,而不能是无限的。“有穷性”往往指“在合理范围之内”。如果写一个需要十年完成运算的算法那它也不是一个有效算法。

2. 确定性。

        算法中每一个步骤都应当是确定的,而不应当是含糊的、模棱两可的。即算法的含义应当是唯一的,而不应当产生“歧义性”。所谓“歧义性”,指可以被理解为两种及以上的可能含义。

3. 有零个或多个输入。

        所谓输入是指在执行算法时需要从外界取得必要的信息。

4. 有一个或多个输出。

        算法的目的是为了求解,“解”就是输出。但算法的输出并不一定就是计算机的打印输出或屏幕输出,一个算法得到的结果就是算法的输出,没有输出的算法是没有意义的。

5. 有效性。

        算法中的每一个步骤都应当能有效地执行,并得到确定的结果。

怎样表示一个算法

自然语言

        简单算法举例,就是用自然语言表示的。他通俗易懂,但文字冗长,容易出现歧义。且自然语言描述包含分支与循环的算法时不方便。

流程图

        流程图是用一些图框来表示各种操作,用图形表示算法,直观形象,易于理解。

常用的流程图符号(如下图)

        菱形框的作用是对一个给定条件进行判断,根据给定条件是否成立决定如何执行其后的操作。他有两个出口Y(是)和N(否)。

        注释框并不是流程图中的必要部分,不反应操做和流程,只是对某些框的操作进行补充说明,以提升流程图的可阅读性。

        连接点(小圆圈)是用于将画在不同地方的流程线连接起来。如下图中有两个以①为标志的两节点,他表示这两个点是连接在一起的,实际上他们是同一个点,只是画不下才分开来画。用连接点可以避免流程线交叉或过长,是流程图清晰。

求1×2×3×4×5用流程图表示

        设置两个变量t,i。t代表被乘数,i代表乘数。将每一次相乘的积放入被乘数变量t中。

        下图右边多了一个输出框,将最后结果输出。

在50个学生中,输出成绩在80分之上的学号和成绩用流程图表示

        用n代表学生学号,下标i代表第几个学生,ni代表第i个学生学号,g代表学生成绩,gi代表第i个学生成绩。

        此图左边中没有包括输入50个学生数据的部分,右边包括了输入学生数据部分。

判定2000-2500年中的每一年是否为闰年用流程图表示

        设置year为被检测的年份

求1-1/2+1/3-1/4+...+1/99-1/100的值用流程图表示

        sign代表当前处理项前的数值符号,term代表当前项的值,sum代表当前各项的累加和,deno是当前项的分母。

给出一个大于或等于3的正整数,判定是否为素数用流程图表示

        设定被除数n,除数i

PS:由以上例子可知,一个流程图包括了,表示相应操作的框、带箭头的流程线、框内外必要的说明文字三个部分。流程线必须要画箭头,他是反映流程的先后的。

三种基本结构和改进的流程图
传统流程图的弊端

        传统流程图用流程线指出各框的执行顺序,对流程线的使用没有严格限制。因此,使用者可以不受限制的使流程随意地转来转去,使流程图变得毫无规律,阅读时需要大量精力去跟踪流程,使人难以理解算法的逻辑。这种如同乱麻一样的算法被称为BS型算法。

        这样的算法是不好的,难以阅读,也难以修改,从而使算法的可靠性和可维护性难以保证。为了提高算法的质量,使算法的设计和阅读方便,必须限制箭头的滥用,即不允许无规律地使流程随意转向,只能顺序的进行下去。但是,算法上难免包含一些分支和循环,从而不可能全部由一个个顺序框组成。所以,规定了几种基本结构,然后由这些基本结构按一定规律组成一个算法结构,使算法的质量得到保证和提高。

三种基本结构

1.顺序结构

        虚线框内是一个顺序结构,其中A、B框使顺序执行的。

2.选择结构

        选择结构又称选取结构或分支结构,下图虚线框内是一个选择结构。此结构中必定包含一个判断框。根据给定的条件p是否成立而选择执行A框或B框。

PS:无论条件是否成立,只能执行A、B框之一,不可能都执行。无论执行哪一个框都必须经过b点,然后脱离本选择结构。A或B框中可以有一个是空的,即不执行任何操作。

3.循环结构

        循环结构又称重复结构,即反复执行某一部分的操作。

当行(while型)循环结构

        当给定条件p1成立时,执行A框操作,执行完A后,在判断p1条件是否成立,如果仍然成立,再执行A框操作,如此反复执行A框,直到某一次p1条件不成立,此时从b点脱离循环结构。

        右图为例子,输出5个数,1,2,3,4,5

    

直到型(until型)循环结构

        执行A框操作,再判断p2条件是否成立,如果不成立,再执行A框操作,再判断p2条件是否成立,如不成立,又执行A框操作,如此反复执行A框,直到某一次p2条件成立,此时从b点脱离循环结构。

        右图为例子,输出5个数,1,2,3,4,5

   

以上三种结构有以下共同特征

1. 只有一个入口。

2. 只有一个出口。注:一个判断框有两个出口,而一个结构只有一个出口。

3. 结构内地每一部分都有机会被执行到。

4. 结构内不存在“死循环(无终止的循环)”。

        由基本结构所构成的算法属于“结构化”算法,它不存在无规律的转向,只在本基本结构内才允许存在分支和向前或向后的跳转。

        只要具备以上四个特点的都可以作为基本结构。

N-S流程图

PS:个人目前感觉不好用,所以在此简单介绍。

        再此流程图中完全去除了带箭头的流程线。全部算法写在一个矩形框内,该框由一些基本框组成一个很大的框。

顺序结构

选择结构

循环结构

上面3个图中A、B框可以是简单的操作,也可以是三种基本结构之一。

例子:

求5!

输出50名学生中高于80分的学号和成绩

判定闰年

求1-1/2+1/3-1/4+...+1/99-1/100的值

判定素数

        由以上例子可知,N-S图表法比文字表述直观、形象、易于理解;比传统流程图紧凑易画,尤其是它废除了流程线,整个算法结构是由各个基本结构按顺序组成。用N-S表示的算法都是结构化的算法。

        一个结构化的算法是由一些基本结构顺序组成的;在基本结构中不存在向前或向后的跳转,流程的转移只存在与一个基本结构范围之内;一个非结构化的算法可以用一个等价的结构化算法代替,其功能不变。如果一个算法不能分解成若干个基本结构,则它必然不是一个结构化算法。

伪代码

        因为修改流程图麻烦,所以他往往用来表示一个算法,而在设计算法使常使用伪代码。

        伪代码是用介于自然语言和机器语言之间的文字和符号来描述算法。它如同一篇文章一样自上而下写,每行(或几行)表示一个基本操作。书写方便、格式紧凑、修改方便、容易看懂,也便于向计算机语言(即程序)过度。用伪代码写的算法无固定的、严格的语法规则。自需要把意思表达清晰,便于书写和阅读即可,书写的格式要写成清晰易读的形式。

例子:

求5!

begin

        1=>t

        2=>i

        while i<=5

                {

                t*i=>t

                i+1=>i

                }

        print t

end

        由例子可知,伪代码书写格式比较自由,容易表达出设计者的思想,同时算法容易修改。用伪代码很容易写出结构化的算法,但是不如流程图只观,可能出现逻辑上的错误。

计算机语言

        完成一项工作,包括设计算法和实现算法。要得到运算结果,必须实现算法。实现算法的方式可能不止一种。用计算机语言表示算法必须严格遵循所用语言的语法规则。

用C语言实现求5!

#include<stdio.h>

int main()

        {

        int t,i;

        t=1;

        i=2;

        while(i<=5)

                {

                t=t*i;

                i=i+1;

                }

        printf("%d\n",t);

        return 0;

        }

用C语言求1-1/2+1/3-1/4+...+1/99-1/100的值

#include<stdio.h>

int main()

        {

        int sign=1;

        double deno=2.0,sum=1.0, term;        //定义deno、sum、term为双精度型变量

        while(deno<=100)

                {

                sign=-sign;

                term=sign/deno;

                sum=sum+term;

                deno=deno+1;

                }

        printf("%f\n",sum);

        return 0;

        }

        只写出来C程序仍然只是描述算法,并未实现算法。只有运行程序才是实现算法。

结构化程序设计方法

        一个结构化程序就是用计算机语言表示的结构化算法,用三种基本结构组成的程序必然是结构化程序。这种程序便于编写、阅读、修改和维护,这减少了程序出错的机会,提高了程序的可靠性,保证了程序质量。

        结构化程序设计强调了程序设计风格和程序结构化的规范,提倡清晰的结构。结构化程序的基本思路是:把一个复杂问题的求解过程分阶段进行,每个阶段处理的问题都控制在人们容易理解和处理的范围内。

保证程序结构化的方法:

1. 自顶向下

        此方法考虑周全,结构清晰,层次分明,作者容易写,读者容易看,修改方便。

2. 逐步细化

        这种方法的过程是将问题求解抽象逐步具体化的过程。便于验证算法的正确性。

3. 模块化设计

        此方法是将一个程序模块,根据不同的功能将其分为若干个子模块,若子模块还大,可以继续划分。程序中的子模块通常用C语言中函数来实现。

        程序中的子模块通常不超过50行,打印输出时不超过一页,这样的规模便于组织,也便于阅读。划分模块时,应注意模块的独立性,即使用一个模块完成一项功能,耦合性越少越好。

4. 结构化编码

        结构化程序设计是用来解决人脑思维能力的局限性和被处理问题的复杂性之间的矛盾。

        设计好结构化算法后,还要善于结构化编码。所谓编码就是将已设计好的算法用计算机语言来表示,即根据已经细化的算法正确的写出计算机程序。结构化的语言都有与其三种基本结构对应的语句。

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号