1.程序=算法+数据结构
一个程序主要包括以下两方面的信息:
(1)对**数据**的描述。在程序中要指定用到哪些数据,以及数据的类型和数据的组织形式。这就是**数据结构(data structure)**。
(2)对**操作**的描述。要求计算机进行操作的步骤,也就是**算法(algorithm)**。
著名计算机科学家沃斯(Nikiklaus Wirth)提出一个公式:
**算法+数据结构=程序**
一个程序员应该具备四个方面的知识:**算法、数据结构、程序设计方法和语言工具**。算法是灵魂,数据结构是加工对现象,语言是工具,编程需要采用合适的方法。
算法是解决“做什么”和“怎么做”的问题。
2.什么是算法
做任何事情都有一定的步骤。
广义上讲,算法就是,为解决一个问题而采取的方法和步骤。
狭义上讲,计算机算法,计算机执行的算法。
计算机算法可以分为两大类别:**数值运算算法**和**非数值运算算法**。数值运算的目的是求数值解。非数值运算种类繁多,要求各异,难以做到全部有现成的答案,因此只有一些典型的非数值运算算法(排序算法、查找搜索算法)有现成的、成熟的算法可供使用。
3. 简单算法举例
例1 求1*2*3*4。
引申:1*2*3*4*...*1000
——>分析:
设置两个变量,一个变量代表被乘数,一个变量代表乘数。不另设变量存放乘积结果,而是直接将每一步骤的乘积放在乘积变量当中。
例2 有50个学生,要求输出成绩80分以上的学生的学号和成绩。
——>分析:
最好使用数组,a[n],a[1]——a[50],用n代表学生学号,用a[n]代表学生成绩。
通过循环嵌套判断,输出成绩80分以上的学生的学号和成绩。
例3 判定2000——2500年中每一年是否为闰年,并将结果输出。
——>分析:
闰年的条件
(1)能被4整除,但不能被100整除的是闰年。
(2)能被400整除的是闰年。
例4 求1-1/2+1/3-1/4+...+1/99-1/100。
——>分析:
(1)每一项分子为1,第二项开始分母为前一项分母加1
(2)分母为偶数时,符号位为负。
例2.5 给出一个大于或等于3的正整数,判断它是不是素数。
——>分析:
(1)素数(**prime**),是指除了1和它本身以外,不能被其他任何整数整除的数。
(2)判断一个数n(n>=3)是否为素数:将n作为被除数,将2~n-1之间的所有整数作为除数,如果被整除,则n是素数。
4.算法的特性
(1)**有穷性**。一个算法应包含有限操作步骤,而不能是无限的。
(2)**确定性**。算法中的每一个步骤都应当是确定的,而不是含糊的、模棱两可的。
(3)**有零个或多个输入**。所谓输入是指在执行算法时需要从外界取得必要的信息。
(4)**有一个或多个输出**。算法的目的是求解,“解”就是输出。
(5)**有效性**。算法的目的是为了求解,并得到确定的结果。
*对于程序员来说,必须学会设计常用的算法,并且根据算法编写程序*。
5.怎样表示一个算法
表示一个算法的常用方法:
自然语言、传统流程图、结构化流程图和伪代码
5.1 用自然语言表示算法
5.2 用流程图表示算法
一个流程图包括以下几个部分:
(1)表示相应操作的框;
(2)带箭头的流程线;
(3)框内外必要的文字说明。
N-S结构化流程图
5.3 三种基本结构和改进的流程图
1.传统流程图的弊端
对流程线没有严格的限制,使用者随心所欲转来转去。阅读时要化很大精力去追踪流程图。如同乱麻的算法称为**BS型算法**,意为一碗面条(**a bowl of spanghetti**),毫无头绪。
为了提高算法的质量,使算法的设计和阅读方便,必须限制箭头的滥用,不允许随意转向,只能顺序地进行下去。
2.三种基本结构
1966年,Bohra和Jacobs在《算法设计语言》一书中提出了三种基本结构:**顺序结构**、**选择结构**和**循环结构**。
(1)**顺序结构**。
(2)**选择结构**。选择结构又称为选取结构或分支结构。
(3)**循环结构**。又称为重复结构,即反复执行某一部分的操作。有两类循环结构。
①**当型(while型)循环结构**。条件成立循环,不成立退出循环。
②**直到型(until型)循环结构**。条件不成立循环,成立退出循环。
以上3种基本结构,有以下共同特点:
1.只有一个入口。
2.只有一个出口。
3.结构内的每一部分都有机会被执行到。
4.结构内不存在“死循环”(无终止的循环)。
**由以上3种基本结构顺序组成的算法结构,可以解决任何复杂的问题**。
5.4 用N-S流程图表示算法
1973年,美国学者I.Nassi和B.Shneiderman提出了**N-S结构化流程图**。
归纳:**一个结构化的算法是由一些基本结构顺序组成的**;在基本结构之间不存在向前或向后的跳转,流程的转移只存在于一个基本结构范围之内;一个非结构化的算法可以用一个等价的结构化算法代替,其功能不变。如果一个算法不能分解为若干个基本结构,则它不是结构化的算法。
5.5 用伪代码表示算法
为了设计算法时的方便,常用一种称为伪代码(***pseudo code***)的工具。
**伪代码是用介于自然语言和机器语言之间的文字和符号来描述算法。**
*用伪代码写算法并无固定的、严格的语法规则,可以用英文,也可以中英文混用。只要把意思表达清楚,便于书写和阅读即可,书写的格式要写成清晰易读的形式。*
例 2.16 求5!,用伪代码表示的算法如下;
```
begin (算法开始)
1=>t
2=>i
while i<=5
{
t*i=>t
i+1=>i
}
printf t
end (结束)
```
5.6 用计算机语言表示算法
要完成一项工作,包括设计算法和实现算法两个部分。
描述算法,用不同的方法来表示操作的步骤.
实现算法,实现的方式不止一种。
计算机实现算法,计算机无法识别流程图和伪代码,只有用计算机语言编写的程序才能被计算机执行,因此用流程图或伪代码描述算法后,还要将其转换成计算机语言。**用计算机语言表示的算法是计算机能够执行的算法**。
**用计算机语言表示算法必须严格遵循所用的语言的语法规则。**
例 2.18 求5!,用C语言表示的算法如下:
'''
#include <stdio.h>
int main()
{
int i,t;
t=1;
i=2;
while(i<=5)
{
t=t*i;
i=i+1;
}
printf("%d",t);
return 0;
}
'''
'''
输出:
120
'''
例 2.19 求多项式1-1/2+1/3-1/4+1/5-1/6+...+1/99-1/100的值,用C语言表示的算法如下:
'''
#include <stdio.h>
int main()
{
int sign=1;
double demo=2.0,sum=1.0,term;
while(demo<=100)
{
sign=-sign;
term=sign/demo;
sum=sum+term;
demo=demo+1;
}
printf("%f",sum);
return 0;
}
'''
'''
输出:
0.688172
'''
6.结构化程序设计方法
怎么样才能得到一个结构化的程序呢?
**结构化程序设计方法的基本思路是:把一个复杂问题的求解过程分阶段进行,每个阶段处理的问题都控制在人们容易理解和处理的范围内。**
方法:
(1)**自顶向下**;
(2)**逐步细化**;
(3)**模块化设计**;
(4)**结构化编码**。
**自顶向下,逐步细化**,这种设计方法的过程是将问题求解由抽象逐步具体化的过程。
**模块设计**,根据程序模块的功能将它划分为若干个子模块,如果子模块还过大,可以划分为更小的模块。划分子模块时应当注意**模块的独立性**,即使用一个模块完成一项功能,耦合越少越好。
模块化设计的思想实际上是一种“**分而治之**”的思想,*把一个大任务分为若干个子任务任务,每一个子任务就相对简单了。*
**结构化编码**(coding),所谓编码就是将已设计好的算法用计算机语言来表示,即根据已经细化的算法正确地写出计算机程序。
*关键是掌握算法,有了正确的算法,用任何语言进行编码都不是难事。*
习题
1.什么叫算法?试着从日常生活找3个例子,描述它们的算法。
(1)算法,为解决问题而采取的方法和步骤。
(2)例子1:吃面。买面条——>烧水——>水开下面——>煮面_>放调料——>盛面——>吃面。
例子2:洗衣服。把衣服放洗衣机——>打开洗衣机——>放衣服——>放水——>开始洗。
例子3:口渴。把水放在水壶里——>烧水——>放凉——>把水喝掉。
2.什么叫结构化的算法?为什么要提倡结构化的算法?
(1)结构化的算法,是由一些基本结构顺序组成的,在基本结构之间不能向前或向后跳转,流程的转移只存在于一个基本的等价结构范围之内。
(2)结构化的算法,便于编写、阅读、修改和维护,减少了程序出错的机会,提高了程序的可靠性,保证了程序的质量。
3.什么叫程序化结构设计?它的主要内容是什么?
结构化程序设计是:
自顶向下、逐步求精;其程序结构是按功能划分为若干个基本模块;各模块之间的关系尽可能简单,在功能上相对独立;每一模块内部均是由顺序、选择和循环三种基本结构组成;其模块化实现的具体方法是使用子程序。结构化程序设计由于采用了模块分解与功能抽象,自顶向下、分而治之的方法,从而有效地将一个较复杂的程序系统设计任务分解成许多易于控制和处理的子任务,便于开发和维护。
主要内容:
结构化程序设计方法具有很多的优点,但它是一种面向过程的程序设计方法,它把数据和处理数据的过程分离为相互独立的实体。当数据结构改变时,所有相关的处理过程都要进行相应的修改,每一种相对于老问题的新方法都要带来额外的开销,程序的可重用性差。