Transcript c_program_2

第2章
算法--程序的灵魂
主要内容







2.0 程序
2.1 算法的概念
2.2 简单算法举例
2.3 算法的特性
2.4 怎样表示一个算法
2.5 程序化设计方法
练习c-2
2.0 程序
 问题分析
 利用计算机处理问题的过程
程序设计的难
点在哪里?
●
算法——程序设计的“灵魂”
 程序的内容
 (沃思 Nikiklaus Wirth):
数据结构
+
(data structure)
算法
=
程序
(algorithm)
 程序=算法+数据结构+程序设计方法+语言工具和环境
 数据结构:对数据的描述,即在程序中要指定数据的类
型和数据的组织形式
 算法:对操作的描述,即操作步骤
 对同一个问题,可以有不同的解题方法和步骤
 为了有效地进行解题,需要保证算法正确,并选择合适的算
法
 特性:有穷性、确定性、有0个或多个输入、有1个或多个
输出、有效性
 上述四个方面中:
算法是灵魂
数据结构是加工对象
语言是工具
编程需要采取合适的方法
 算法解决"做什么"和"怎么做"的问题
 程序中的按一定顺序列出的操作语句,就是算法的体现
 通过本门课,大家学会使用c语言的语法编写不太复杂
的c程序
2.1 算法的概念
 广义的说,为解决一个问题而采取的方法和步骤,
就称为算法
 计算机算法
 用计算机解决问题的步骤
 分类
 数值运算算法
 非数值运算算法
2.2 简单算法举例
例2.1
求1×2×3×4×5
原始方法:
改进算法:
步骤1:先求1×2,得到结果2。
设t为被乘数,i为乘数,用循环
法求解
S1: 使 t=1
S2: 使 i=2
S3: 使 t×i,乘积仍然放在变量
t中,可表示为t×i→t
S4: 使i的值+1,即i+1→i
S5: 如果i≤5, 返回重新执行
步骤S3以及其后的S4和S5;
否则,算法结束。最后得到
t的值就是5!的值
步骤2:将步骤1得到的乘
积2乘以3,得到结果6。
步骤3:将6再乘以4,得24。
步骤4:将24再乘以5,得120。
若求 1×2×…×1000,
怎么做?
思考:
若求
1×3×5…×1001,
怎么做?
例2.2
有50个学生,要求将他们之中成绩在80分以上者打印出来
设ni:第i个学生学号
gi:第i个学生成绩
算法如下:
S1:
1→i
S2:
如果 gi≥80,则输出 ni和 gi,否则不输出
S3:
S4:
i+1→i
若i≤50, 返回S2,否则,算法结束
例2.3
判定2000 — 2500年中的每一年是否闰年,将结果输出。
闰年的条件:
能被4整除: 但不能被100整除的年份;
能被100整除,又能被400整除的年份;
 算法如下:











设y为被检测的年份。
S1: 2000→y
S2: 若y不能被4整除,则输出y“不是闰年”,
然 后转到S6
S3: 若y能被4整除,不能被100整除,则输
出y“是闰年”,然后转到S6
S4: 若y能被100整除,又能被400整除,输
出y“是闰年” 否则输出y“不是闰年”,
然后转到S6
S5: 输出y“不是闰年”
S6: y+1→y
S7: 当y≤2500时, 返回S2继续执行,否则,算法结束
2.3 算法的特性
 有穷性:一个算法应包含有限的操作步骤而不能是无限的
 确定性:算法中每一个步骤应当是确定的,而不能应当是含
糊的、模棱两可的不应产生歧义性
 输入:有零个或多个输入
 输入是指在执行算法时需要从外界取得必要的信息
 输出:有一个或多个输出
 算法的目的是为了求解,“解”就是输出
 有效性:算法中每一个步骤应当能有效地执行,并得到确定
的结果
a
b
算法:
c
求3个数中最大的数
3个数中最大的数
2.4 怎样表示一个算法
 怎样表示一个算法?





用自然语言表示
用流程图表示(传统流程图和N-S图)
用伪代码表示
用计算机语言表示
结构化程序的三种基本结构
顺序、选择、循环
 用自然语言表示算法
 自然语言指人们日常使用的语言,如汉语、英语等
 用自然语言表示算法的特点:
 通俗易懂,但不严谨,容易产生歧义
 除非问题很简单,一般不用自然语言描述算法
 用流程图表示算法
 用传统流程图表示
 用N-S流程图表示
 程序设计的过程,
实际上就是确定解决问
题的详细步骤,而这些
步骤通常称为流程。
 用传统流程图表示
算法
 流程图采用一些图
形框表示算法要表
述的各种操作
直观、形象
 ANSI规定的常用
流程图符号
起止框
输入输出框
判断框
处理框
连接点
流程线
注释框
例2.6
示
将例2.1
求1×2×3×4×5
的算法用流程图表
改进算法:
开始
设t为被乘数,i为乘数,用循环
法求解
S1: 使 t=1
S2: 使 i=2
S3: 使 t×i,乘积仍然放在变量
t中,可表示为t×i→t
S4: 使i的值+1,即i+1→i
S5: 如果i≤5, 返回重新执行
步骤S3以及其后的S4和S5;
否则,算法结束。最后得到
t的值就是5!的值
1=>t
2=>i
t× i=>t
i+1=>i
真
i≤5
假
输出t的值
结束
 传统流程图的特点
 传统流程图的构成
 表示相应操作的框
 带箭头的流程线
 框内外必要的文字说明
 优点
 直观形象
 弊端
 占用篇幅较多
 流程线使用无限制,乱无头绪(BS型算法)
 3种基本结构:
顺序、选择、循环结构
用这3种基本结构作为表示一个良好算法的基本单元
 顺序结构
a
A
虚线框内是一个顺序结构。
A、B两个框是顺序执行的:
按图中所画的框的顺序,先
B
b
执行A操作,再执行B操作。
 选择结构(选取结构/分支结构)
虚线框内是一个选择结构。
a
成立
条件P
不成立
此结构必须包含一个判断框,框中写有
一个条件,根据给定的条件是否成立,
从而选择执行A框或是B框。
例如:条件可以是i≤101
A
a
B
成立
条件P
b
A
b
不成立
B操作
为空时,
画成直
线
 循环结构
 直到型---until型
山无棱,天地合,乃敢与君绝!
虚线框内是一个直到型
循环结构。
a
先执行A框中的操作;
执行完A操作后,判条件
P是否成立;
A
不成立
条件P2
成立
b
如果不成立,继续执行A
操作;
如此反复执行A框中的操
作,直到条件P成立为止,
从b点脱离本循环结构。
 当型---while型
当山峰没有棱角的时候 当河水不在流
当时间停住日月不分 当天地万物化为虚
有 我还是不能和你分手
虚线框内是一个当型循环
结构。
a
条件P1
成立
A
不成立
当给定的条件成立时,执
行A框中的操作;
执行完A操作后,判条件P
是否成立;
如果仍成立,继续执行A操
作;
b
如此反复执行A框中的操作,
直到条件P不成立为止,从
b点脱离本循环结构。
 结构化程序设计方法
 三种基本结构的共同点
 只有一个入口
 只有一个出口
 结构内每一部分都有机会被执行到
 结构内不存在"死循环"。 如条件永远成立时,就成了"死
循环“
注意:基本结构并不只限于上面3种,只要符合上述的四
个特点的结构,都称为基本结构
 已经证明,用以上三种基本结构顺序组成的算法结构,可以
解决任何复杂的问题
 由基本结构构成的算法属于“结构化”的算法,它不存在无规律
的转向,只在本基本机构内才允许存在分支和向前或向后的
跳转
 用N-S流程图表示算法
 用基本结构的顺序组合可以表示任何复杂的算法结
构,那么,就可去掉流程线,避免了随意的跳转
 1973年两名美国学者提出了一种新的流程图形式
,并用二人名字的第一个字母组合命名了该流程图
。即N-S流程图,也称盒图
 三种基本结构的表示
A
成立
P
P1
B
A
顺序结构
A
不成立
B
选择结构
A
当型循环结构
P2
直到型循环结构
例2.11
表示
将例2.1
求1×2×3×4×5
的算法用N - S图
改进算法:
1=> t
设t为被乘数,i为乘数,用循环
法求解
S1: 使 t=1
S2: 使 i=2
S3: 使 t×i,乘积仍然放在变量
p中,可表示为t×i→t
S4: 使i的值+1,即i+1→i
S5: 如果i≤5, 返回重新执行
步骤S3以及其后的S4和S5;
否则,算法结束。最后得到
t的值就是5!的值
A
2=>i
这是一
个顺序
结构
t x i=> t
i+1=>i
直到 i>5
这两个操
作之间是
顺序关系
B
这是一
个循环
结构
输出t的值
上述算法由基
本结构组成
 N-S图表示算法的优点
 比文字描述直观、形象、 易于理解
 比传统流程图紧凑易画。尤其是它废除了流程线,整个
算法结构是由各个基本结构按顺序组成的,N--S流程
图中的上下顺序就是执行时的顺序
 用N--S图表示的算法都是结构化的算法,因为它不可
能出现流程无规律的跳转,而只能自上而下地顺序执行
 小结
 一个结构化的算法是由一些基本结构顺序组成的。在基
本结构之间不存在向前或向后的跳转,流程的转移只存
在于一个基本结构范围之内(如循环中流程的跳转)
 一 个非结构化的算法可以用一个等价的结构化算法代
替,其功能不变 。如果一个算法不能分解为若干个基
本结构,则它必然不是一个结构化的算法
 用伪代码表示算法
 伪代码
 是用介于自然语言和计
算机语言之间的文字和
符号来描述算法
 优点
书写方便,格式紧凑,
易懂,易改,便于向计
算机语言过渡
 缺点
不如流程图直观,可能
会出现逻辑上的错误
例2.16
将例2.1 求
1×2×3×4×5 的算法用伪
代码表示
开始
置t的初值为1
置i的初值为2
当i <= 5 时,执行下面的
操作:
使 t=t x i
使 i=i+1
输出 t 的值
结束
 用计算机语言表示算法—实现算法
 只有用计算机语言描述的算法才能被计算机的编译
环境识别,并被处理、执行
 用计算机语言表示算法必须严格遵守所用语言的语
法规则
 前面几种描述算法的方法对文字等格式要求不严,
一般来说,只要能示意就行
例2.18
将例2.1 6 表示的求5!的算法用C语言表示
#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;
}
 程序设计步骤






分析问题
确定解决方案
建立数学模型
设计算法
用计算机语言描述算法(即写出源程序)
上机调试源程序:经过编辑、编译、连接、运行,得到
可执行的程序。(参看P13图1.2 )
 运行程序,得到需要的结果
 说明:
写出了C程序,仍然只是描述了算法,并未实现算
法。只有运行程序才是实现算法。应该说,用计算
机语言表示的算法是计算机能够执行的算法
2.5 结构化程序设计方法
 一个结构化程序 就是用高级语言表示的结构化
算法。用三种基本结构组成的程序必然是结构
化的程序,这种程序便于编写、便于阅读、便
于修改和维护
 结构化程序设计强调程序设计风格和程序结构
的规范化,提倡清晰的结构
 结构化程序设计方法的基本思路
把一个复杂问题的求解过程 分阶段进行,每个阶段
处理的问题都控制在人们容易理解和处理的范围内
用这种方法逐步分解,直到作者认为可以直接将
各小段表达为文字语句为止。这种方法就叫 做“自顶
向下,逐步细化”。
 自顶向下,逐步细化方法的优点:
 考虑周全,结构清晰,层次分明,作者容易写,读
者容易看
 如果发现某一部分中有一段内容不妥,需要修改,
只需找出该部分修改有关段落即可,与其它部分无
关
 提倡用这种方法设计程序。这就是用工程的方法设
计程序
 模块设计的方法
 模块化设计的思想实际上是一种“分而治之”的思想
,把一个大任务分为若干个子任务,每一个子任务
就相对简单了
 在拿到一个程序模块以后,根据程序模块的功能将
它划分为若干个子模块,如果这些子模块的规模还
嫌大,还再可以划分为更小的模块。这个过程采用
自顶向下方法来实现
 子模块一般不超过50行
 划分子模块时应注意模块的独立性,即:使一个模
块完成一项功能,耦合性愈少愈好
练习2-1(该作业交纸质)
 P36 练习2.1
 注:只找一个例子,描述方法自选
 P36 练习2.4.5,要求
 画传统流程图
 画N-S流程图
 用伪代码描述算法