c完全讲义pptunit.ppt_第1页
c完全讲义pptunit.ppt_第2页
c完全讲义pptunit.ppt_第3页
c完全讲义pptunit.ppt_第4页
c完全讲义pptunit.ppt_第5页
已阅读5页,还剩102页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第二章基本控制结构程序设计 结构化程序设计的特点是任何程序都可由三种基本结构及其组合来描述 本章将介绍C 分支结构和循环结构的设计方法 还将介绍一些常用算法 第二章基本控制结构程序设计 2 2分支结构程序设计 2 7枚举类型 2 6常用算法的应用实例 2 4转向语句 2 3循环结构程序设计 2 8输入输出文件简介 2 5结构化程序设计思想 选读 2 1算法的概念与表示方法 2 1算法的概念与表示方法 2 1 1算法的概念 2 1 3算法描述的三种基本结构 2 1 2算法的表示 2 1 1算法的概念 算法 算法是解决问题的步骤 计算机算法的特征 可执行性确定性有穷性可输入输出信息算法是程序设计学习的重点 2 1 2算法的表示 流程图 流程图是图形化的表示方法 比较直观 基本组成元件包括矩形框 菱形框 箭头线等 其中矩形框表示要执行的指令 在框内标注指令内容 菱形框表示要判断其中表达式的值是真还是假 箭头线则标示指令的流程方向 伪码 伪码是介于自然语言和程序设计语言之间的一种类自然语言的表示方法 书写形式自由 容易转换为程序 2 1 3算法描述的三种基本结构 3循环结构 1顺序结构 2分支结构 算法的基本结构 对算法的理论研究和实践表明 任何算法的描述都可以分解为三种基本结构或它们的组合 这三种基本结构是顺序结构 分支结构和循环结构 num1 15 2 1 3算法描述的三种基本结构 1 顺序结构 例2 1 求两数之和 流程图 显示结果 35 num2 20 sum num1 num2 演示算法执行过程 输出sum 2 1 3算法描述的三种基本结构 2 分支结构 例2 2 输入三个数 输出其中的最大数 x 7 y 12 z 10 if x y max x elsemax y if z max max z 输出max 显示结果 12 流程图 块1 块2 真 假 演示算法执行过程 2 1 3算法描述的三种基本结构 例2 3 求4个整数的和 显示结果 60 演示算法执行过程 12 3 14 26 2 16 42 1 18 60 0 count 4 整数个数sum 0 累加和的初值while count 0 x 输入一个整数 sum sum x count count 1 输出sum 2 2分支结构程序设计 对程序的运行流程进行控制 主要通过执行专门用来控制流程的语句来实现 分支语句是基本流程控制语句之一 C 提供三种分支语句 2 2 1if语句 2 2 2if语句的嵌套 2 2 4swich语句 2 2 3条件运算符 2 2 1if语句 if语句基本格式 1 if 表达式 语句1 2 if 表达式 语句1 else语句2 例2 4 输入一个年份 判断是否闰年 例2 5 从键盘上输入三个整数 输出其中的最大数 嵌套if语句 if语句中 如果内嵌语句又是if语句 就构成了嵌套if语句 if语句可实现二选一分支 而嵌套if语句则可以实现多选一的多路分支情况 嵌套有两种形式 嵌套在else分支中 if 表达式1 语句1 elseif 表达式2 语句2 elseif else语句n 嵌套在if分支中 if if else 2 2 2if语句的嵌套 例2 6 用嵌套if语句完成 例2 5 的任务 else和if的配对关系 C 规定了if和else的 就近配对 原则 即相距最近且还没有配对的一对if和else首先配对 按上述规定 第二种嵌套形式中的else应与第二个if配对 如果根据程序的逻辑需要改变配对关系 则要将属于同一层的语句放在一对 中 如第二种嵌套形式中 要让else和第一个if配对 语句必须写成 if 表达式1 if 表达式2 语句1 else语句2 第二种嵌套形式较容易产生逻辑错误 而第一种形式配对关系则非常明确 因此从程序可读性角度出发 建议尽量使用第一种嵌套形式 2 2 2if语句的嵌套 配对关系实例 语句1 if n 3 0 if n 5 0 cout n 是15的倍数 endl elsecout n 是3的倍数但不是5的倍数 endl 语句2 if n 3 0 if n 5 0 cout n 是15的倍数 endl elsecout n 不是3的倍数 两个语句的差别只在于一个 但表达的逻辑关系却完全不同 例2 7 某商场购物优惠活动 例2 8 求一元二次方程的根 2 2 3条件运算符 三元运算符 三元运算符条件运算符 可以用来简化if语句表达 其构成的表达式格式为 表达式1 表达式2 表达式3例如 inta 6 b 7 min a b a b min 6min a b a b min 7a 7b 7min a b a b min 6a 7b 7 ok 2 2 4switch语句 开关语句 switch语句 用来实现多选一 switch 表达式 case常量表达式 语句序列 break case常量表达式n 语句序列n break default 语句序列 开关语句注意要点 1 各个case 包括default 分支出现的次序可以任意 通常将default放在最后 2 break语句可选 如果没有break语句 每一个case分支都只作为开关语句的执行入口 执行完该分支后 还将接着执行其后的所有分支 因此 为保证逻辑的正确实现 通常每个case分支都与break语句联用 2 2 4switch语句 3 每个常量表达式的取值必须各不相同 否则将引起歧义 4 允许多个常量表达式对应同一个语句序列 例如 charscore cin score switch score case A case a cout excellent break case B case b cout good break default cout fair 5 从形式上看 switch语句的可读性比嵌套if语句好 但不是所有多选一的问题都可由开关语句完成 这是因为开关语句中限定了条件表达式的取值类型 ok 例2 9 运输货物实行分段计费 采用不带break的开关语句实例 例2 10 设计一个计算器程序 实现加 减 乘 除运算 2 2 4switch语句 循环控制语句是基本流程控制语句之一 C 提供三种循环语句 2 3 1while语句 2 3 4循环的嵌套 2 3 3for语句 2 3 2do while语句 2 3循环结构程序设计 2 3 1while语句 while语句也称为当循环 语句格式为 while 表达式 循环体语句 图2 5while语句的执行流程图 求表达式的值 表达式值为真 是 否 执行循环体语句 例2 11 求1 2 3 4 100的值 2 3 1while语句 注意 在有循环语句的程序中 通常循环开始前对循环条件进行初始化 而在循环体语句中要包含修改循环条件的语句 否则循环将不能终止而陷入死循环 C 表达方式灵活 上例中的循环语句还可以写成 while i n sum i 或者while sum i i n 循环体为空语句修改程序后在VC 平台上运行 看是否正确 2 3 2do while语句 do while语句称为直到循环 格式为 do循环体语句while 表达式 否 是 表达式的值为真 执行循环体语句 求表达式的值 图2 6do while语句的执行流程图 2 3 2do while语句 do while语句和while语句的区别 do while语句至少执行一次循环体后再判断循环条件是否满足 while语句先判断条件是否满足 然后才执行循环体 可能一次也不执行 多数情况下可以互相替代 例2 12 用迭代法求a的平方根近似值 例2 13 输入一段文本 统计文本的行数 单词数及字符数 2 3 3for语句 for循环语句的格式为 for 表达式1 表达式2 表达式3 循环体语句 ok for语句 while语句 do while语句比较 inti 1 sum 0 循环初始条件while i 4 sum i i 修改循环条件 inti 1 sum 0 循环初始条件do sum i i 修改循环条件 while i 4 inti sum 0 for i 1 i 4 i sum i 习惯上 表达式1 循环初始条件 表达式2 循环终止条件 表达式3 修改循环条件 ok for语句的应用 for语句的几点说明 1 是先判断型的 同while语句 2 使用更为灵活 三个表达式可以是任意表达式 因此它们就可以实现循环初始化 计算 修改循环条件等任务 而不一定非在循环体中进行 for语句的应用 例2 14 运行结果 01123581321345589144233377610987159725844181 例2 15 输入一个不超过5位的整数 将其反向后输出 例2 14 设计程序输出Fibonacii数列的前20项 2 3 4循环的嵌套 例2 16 打印九九表 嵌套循环 当循环语句中的循环体中又有循环语句时 就构成了嵌套循环 嵌套层次一般不超过3层 以保证可读性 例2 17 打印如下图形 2 4转向语句 break语句 return语句 goto语句 continue语句 2 4转向语句 break语句只能用在switch语句和循环语句中 用来跳出switch语句或提前终止循环 转去执行switch语句或循环语句之后的语句 在for循环中可以用break结束循环 for if break Break语句 例2 18 给定正整数m 判定其是否为素数 2 4转向语句 continue语句只能用在循环语句中 用来终止本次循环 当程序执行到continue语句时 将跳过其后尚未执行的循环体语句 开始下一次循环 下一次循环是否执行仍然取决于循环条件的判断 continue语句与break语句的区别在于 continue语句结束的只是本次循环 而break结束的是整个循环 continue语句 例 输出1 100内3的倍数 分析 设置整型变量I从1变化到100 依次测试I是否3的倍数 算法属于穷举法 for I 1 I 100 I if I 3 0 continue I不是3的倍数 不输出 继续下一个I 输出I的值 I是3的倍数才输出 2 4转向语句 goto语句和标号语句一起使用 所谓标号语句是用标识符标识的语句 它控制程序从goto语句所在的地方转移到标号语句处 goto语句会导致程序结构混乱 可读性降低 而且它所完成的功能完全可以用算法的三种基本结构实现 因此一般不提倡使用goto语句 但在某些特定场合下goto语句可能会显出价值 比如在多层循环嵌套中 要从深层地方跳出所有循环 如果用break语句 不仅要使用多次 而且可读性较差 这时goto语句可以发挥作用 goto语句 2 4转向语句 return语句用于结束函数的执行 返回调用者 如果是主函数 则返回至操作系统 利用一个return语句可以将一个数据返回给调用者 通常 当函数的返回类型为void时 return语句可以省略 如果使用也仅作为函数或程序结束的标志 return语句 2 5结构化程序设计思想 选读 传统的程序设计方法可以归结为 程序 算法 数据结构 将程序定义为处理数据的一系列过程 这种设计方法的着眼点是面向过程的 特点是数据与程序分离 即数据与数据处理分离 结构化程序设计的基本思想是采用自顶向下 逐步细化的设计方法和单入单出的控制结构 结构化程序设计方法 2 5结构化程序设计思想 选读 举一个简单的例子 要求读入一组整数 统计其中正整数和负整数的个数 该任务的模块结构及细化过程如下 2 5结构化程序设计思想 选读 1 难以适应大型软件的设计 由于数据与数据处理相对独立 在大型多文件软件系统中 随着数据量的增大 程序越来越变得难以理解 多个文件之间的数据沟通也变得困难 还容易产生意想不到的结果 即所谓副作用 2 程序可重用性差 处理方法的改变或数据类型的改变都将导致重新设计 这种额外开销与可重用性相左 称为重复投入 结构化程序设计缺陷 2 6常用算法的应用实例 例2 20 世界数学史上著名的 百鸡问题 例2 21 用欧基里德算法 也称辗转法 求两个整数的最大公约数 例2 23 输入一个8位二进制数 将其转换为十进制数输出 例2 19 用筛选法求100之内的所有素数 例2 22 输入一个小于1的数x 求sinx的近似值 2 7枚举类型 2 7 1枚举类型的定义 2 7 2枚举变量的使用 枚举类型 enumerate 是c 中的一种派生数据类型 它是用户定义的若干枚举常量的集合 枚举类型的变量 只能取枚举常量表中所列的值 定义枚举类型的主要目的是增加程序的可读性 2 7 1枚举类型的定义 枚举类型定义 enum 关键字enum指明其后的标识符是一个类型的名字 枚举常量表中列出该类型的所有取值 各枚举常量之间以 间隔 例 enmucolor set1 RED BLUE WHITE BLACK enumweek Sun Mon Tue Wed Thu Fri Sat 枚举常量 或称枚举成员 是以标识符形式表示的整型量 非法定义实例 enumletter set a d F s T 枚举常量只能是标识符enumyear set 2000 2001 2002 2003 2004 2005 改为y2000等则正确 2 7 1枚举类型的定义 枚举常量 枚举常量代表该枚举类型的变量可能取的值 编译系统为每个枚举常量指定一个整数值 缺省状态下 这个整数就是所列举元素的序号 序号从0开始 如上例中RED BLUE WHITE BLACK的值分别为0 1 2 3 用户也可以在类型定义时为部分或全部枚举常量指定整数值 在第一个指定值之前的枚举常量仍按缺省方式取值 而指定值之后的枚举常量按依次加1的原则取值 各枚举常量的值可以重复 但各枚举常量标识符必须不同 例 enumfruit set apple orange banana 1 peach grape enumweek Sun 7 Mon 1 Tue Wed Thu Fri Sat 枚举常量apple orange banana peach grape的值分别为0 1 1 2 3 枚举常量Sun Mon Tue Wed Thu Fri Sat的值分别为7 1 2 3 4 5 6 2 7 2枚举类型的变量的使用 枚举类型应用要点 1 定义枚举类型之后 就可以定义枚举类型的变量 亦可类型与变量同时定义 甚至类型名可省 color set1color1 color2 enum Sun Mon Tue Wed Thu Fri Sat weekday1 weekday2 2 枚举变量的取值范围就是整型数的一个子集 枚举变量占用内存的大小与整型数相同 3 枚举变量允许的操作只有赋值和关系运算 如 color3 color4 BLUE if color3 color4 cout 相等 cout color3 WHITE 输出 真 即1 4 枚举变量不能直接输入 可以直接输出 但输出的是变量的整数值 例如 cin color1 非法cout color3 合法 输出的是2从程序的合法性和可读性出发 枚举变量的输入输出一般都采用switch语句将其转换为字符或字符串 同时 枚举类型数据的其他处理也往往应用switch语句 2 7 2枚举类型的变量的使用 例2 24 口袋中有红 黄 蓝 白 黑五种颜色的球若干个 每次从口袋中取三个不同颜色的球 统计并输出所有的取法 2 8输入输出文件简介 使用文件的步骤如下 1 说明一个文件流对象 内部文件 文件流类型ifstream支持从输入文件提取数据的操作 而文件流类型ofstream完成数据写入输出文件的各种操作 ifstreamifile 定义输入文件 ifile为文件名 可用任意标识符ofstreamofile 定义输出文件 ofile为文件名 可用任意标识符 2 打开文件 ifile open d my in file txt ofile open d my out file txt 引号中的 d my in file txt 和 d my out file txt 为磁盘文件路径名 这样在文件流对象和磁盘文件名之间建立了联系 3 对文件进行读写操作 最常见的文件读写是顺序的 所谓 顺序 指的是从文件头开始进行读写 顺序读写可用C 的提取运算符 和插入运算符 进行 也可以用读字符的get 和读字符串的getling 等函数 读写是在文件缓冲区中进行 4 关闭文件 当打开一个文件进行读写后 应该显式地关闭该文件 与打开文件相对应 ifile close ofile close 关闭文件时 系统把与该文件相关联的文件缓冲区中的数据写到磁盘文件中 保证文件的完整 同时把磁盘文件名与文件流对象之间的关联断开 可防止误操作修改了磁盘文件 例2 25 将百鸡问题计算结果存入文件 例2 26 读出存放百鸡问题计算结果的文件 第二章基本控制结构程序设计 结束 欢迎再来 if语句 例2 4 例2 4 输入一个年份 判断是否闰年 算法分析 假定年份为year 闰年的条件是 year 4 0 ok 分析 读入三个数 先求出两个数中较大者 再将该大数与第三个数比较 求出最大数 intmain inta b c max cout a b c coutb max a elsemax b if c max cout 最大数为 c endl elsecout 最大数为 max endl return0 if语句 例2 5 例2 5 从键盘上输入三个整数 输出其中的最大数 ok 方法1 采用if中嵌套形式intmain inta b c max cout a b c coutb if a c max a a b且a celsemax c a b且ac max b acelsemax c a b且b ccout 最大数max max return0 if语句 例2 6 例2 6 用嵌套if语句完成 例2 5 的任务 ok 方法2 采用else中嵌套形式intmain inta b c max cout a b c coutb if语句 例2 6 ok 例2 7 某商场优惠活动规定 某种商品单价为80元 一次购买5件以上 包含5件 10件以下 不包含10件 打9折 一次购买10件以上 包含10件 打8折 设计程序根据客户的购买量计算总价 算法1 输入购买件数count 设置单价price 80 元 2 根据count值确定折扣discount 3 实际售价amount price count discount 4 输出amount的值 算法细化 2 1 if count 5 count 10 discount 0 8 if语句 例2 7 intmain floatprice 80 discount amount 单价 折扣 总价intcount 购买件数cout count if count 5 discount 1 elseif count 10 discount 0 9 elsediscount 0 8 amount price count discount cout 购买件数 count endl cout 单价 price t 折扣 discount endl cout 总价 amount endl return0 请在VC 平台上运行 输入不同的件数 使程序所有分支都可以被执行一次 ok if语句 例2 7 例2 8 求一元二次方程ax2 bx c 0的根 其中系数a a 0 b c的值由键盘输入 分析 输入系数a a 0 b c后 令delta b2 4ac 结果有三种情况 若delta 0 方程有两个相同实根 若delta 0 方程有两个不同实根 若delta 0 方程无实根 if语句 例2 8 include includeusingnamespacestd intmain floata b c floatdelta x1 x2 constfloatzero 0 0001 定义一个很小的常数cout a b c cout a a t b b t c c endl delta b b 4 a c 求一元二次方程的根源程序 if语句 例2 8 if fabs delta 0 delta sqrt delta x1 b delta 2 a x2 b delta 2 a cout 方程有两个不同实根 cout x1 x1 t x2 x2 endl elsecout 方程无实根 endl delta 0return0 请在VC 平台上运行 输入不同的系数 使程序所有分支都可以被执行一次 if语句 例2 8 不带break的开关语句实例 例2 9 运输公司对所运货物实行分段计费 设运输里程为s 则运费打折情况如下 s 250不打折扣250 s 5002 折扣500 s 10005 折扣1000 s 20008 折扣2000 s 300010 折扣3000 s15 折扣设每公里每吨的基本运费为p 货物重量为w 总运输里程在某段中的里程为 s 折扣为d 则该段运费为 p w s 1 d 设计程序 当输入p w和s后 计算运费f 算法 总费用为各段费用之和 可采用不加break的switch语句 分析 switch语句要求条件表达式取值为确定的若干个开关量 而不能使用关系表达式 用里程s进行判断似乎不符合条件 但是分析发现 里程s的分段点均是250的倍数 因此 将里程s除以250 取整数商c 可得到若干整数值 因此算法描述如下 ok 不带break的开关语句实例 switch c default d 0 15 f p w s 3000 1 d s 3000 case8 case9 case10 case11 d 0 1 f p w s 2000 1 d s 2000 case4 case5 case6 case7 d 0 08 f p w s 1000 1 d s 1000 case2 case3d 0 05 f p w s 500 1 d s 500 case1 d 0 02 f p w s 250 1 d s 250 case0 d 0 f p w s 1 d 3000 s15 折扣2000 s 300010 折扣1000 s 20008 折扣500 s 10005 折扣250 s 5002 折扣s 250不打折扣 不带break的开关语句实例 intmain intc s doublep w d f cout p w s f 0 c s 250 switch c default d 0 15 f p w s 3000 1 d s 3000 case8 case9 case10 case11 d 0 1 f p w s 2000 1 d s 2000 case4 case5 case6 case7 d 0 08 f p w s 1000 1 d s 1000 case2 case3 d 0 05 f p w s 500 1 d s 500 case1 d 0 02 f p w s 250 1 d s 250 case0 d 0 f p w s 1 d cout 运输单价 p t 重量 w t 里程 s endl cout 折扣后运费 f endl return0 请在VC 平台上运行 输入不同的里程 例2 10 设计一个计算器程序 实现加 减 乘 除运算 分析 读入两个操作数和运算符 根据运算符完成相应运算 includeusingnamespacestd intmain floatnum1 num2 charop cout num1 op num2 switch op case cout num1 op num2 num1 num2 endl break case cout num1 op num2 num1 num2 endl break case cout num1 op num2 num1 num2 endl break case cout num1 op num2 num1 num2 endl break default cout op 是无效运算符 return0 常量表达式采用字符型 上机运行一下 while语句 例2 11 例2 11 求1 2 3 4 100的值 ok N个连续整数相加算法1 设置变量i用来放加数 变量sum用来放被加数与和值 并初始化 2 从第一个数开始 依次将加数赋给i 并进行操作sum sum i 称为累加 3 输出sum 细化算法2 while 还有加数 i 当前加数 sum i i准备接受下一个加数 源程序如下 includeusingnamespacestd constintn 100 用常变量利于修改程序intmain inti 1 sum 0 循环初始条件while i n sum i i 修改循环条件 cout sum sum endl return0 在VC 平台上运行 试一试是否正确 ok 例2 12 用迭代法求a的平方根近似值 求平方根的迭代公式为 要求前后两个迭代根之差小于10 5 do while语句 例2 12 迭代法求解 a是已知正数 x0是迭代初值 给x0一个值 假定x0 a 2 则用迭代公式依次计算 x1 x0 a x0 2 x2 x1 a x1 2 xk 1 xk a xk 2 当 xk 1 xk 是一个较小的正数 时 迭代终止 取xk 1的值为a的平方根近似值 ok 1 输入a a 0 及较小正数delta 也可用常变量 2 x0 a 2 用迭代公式算x1 x0 a x0 2 3 while x1 x0 delta x0 x1 把最近的值给x0 x1 x0 a x0 2 求xk 1时只需要知道xk的值 所以只需2个变量4 取x1的值为a的平方根近似值 输出 2 3步骤很适合用do while语句实现 x1 a 2 do x0 x1 x1 x0 a x0 2 while x1 x0 delta 和迭代法对应的程序算法是递推算法 intmain floatx0 x1 a cout a if a 1e 5 cout a 的平方根为 x1 endl return0 在VC 平台上运行 输入2 3 4 5试一试是否正确 例2 13 输入一段文本 统计文本的行数 单词数及字符数 假定单词之间以空格或跳格或换行符间隔 且文本开始没有空行 算法分析 1 逐个读入文本中的字符 直到读到一个输入结束符EOF为止 2 如何算行数 行结束标志为读到字符 n 3 如何算单词数 设一个变量isword 读到字符时isword 1 读到间隔符时isword 0 如果读到一个间隔符而此时isword值为1 则说明刚读完一个单词 如果读到一个字符而此时isword值为0 则说明刚开始读一个单词 4 如何算字符数 do while语句 例2 13 ok do while语句 例2 13 算法 1 设置变量line word ch分别代表行数 单词数 非分隔字符数 并初始化 设置变量isword来辅助统计单词数 2 do 从键盘读入一个字符c if c n line if 是单词开头 word if c不是分隔符 ch while c EOF 3 输出统计结果 intmain charc intline 0 word 0 ch 0 intisword 0 cout 输入一段文本 无空行 endl do c cin get if ch n line 遇换行符行数 1if c 例2 14 设计程序输出Fibonacii数列的前20项 要求每行输出5个数据 Fibonacii数列定义如下 算法分析 除了第0项和第1项外 每一项都是由类似方法产生 即前两项之和 所以求当前项时 只需要记住前两项 程序不需要为每一项设置专用变量 属递推算法 for语句的应用 例2 14 算法 1 设置变量n表示第几项 变量f1和f2用来记住当前项f3之前的两项 变量初始化n 0 2 while 当前项不到第20项 if 当前项是第0项 f1 0 if 当前项是第1项 f2 1 if 当前项是第2项或更高项 f3 f1 f2 按要求输出f3 f1 f2 f2 f3 记住最近两项当前项后移一位 程序如下 文件名 Ex2 14 cppintmain intfib0 0 fib1 1 fib2 cout setw 5 fib0 setw 5 fib1 endl for intn 3 n 20 n fib2 fib0 fib1 cout setw 5 fib2 if n 5 0 cout endl 控制每行5个数据fib0 fib1 fib1 fib2 return0 for语句的应用 例2 14 例2 15 输入一个不超过5位的整数 将其反向后输出 例如输入247 变成742输出 算法分析 1 将整数的各个数位逐个位分开 用一个数组保存各个位的值 然后反向组成新的整数 2 将整数各位数字分开的方法是 通过求余得到个位数 然后将整数缩小十倍 再求余 并重复上述过程 分别得到十位 百位 直到整数的值变成0为止 for语句的应用 例2 15 ok 数据处理 1 设置变量num表示输入的整数 整型数组digit 5 用来存放num的各个位 变量i用来表示数组的当前下标 算法 1 输入num 变量初始化 i 0 2 while num 0 num对10取余 得num的当前个位数digit i num整除10 即去掉个位数 十位变个位 百位变十位 i 数组digit准备记录下一位 3 将数组元素按下标从低到高的顺序输出 程序如下 intmain inti num subscript intdigit 5 cout num cout0 for i 0 i subscript i 整数的反向组合num num 10 digit i cout 反向后整数为 num endl return0 在VC 平台上运行 试一试是否正确 循环的嵌套 例2 16 分析 1 计算机的输出是按行进行的 因此可以先用一个循环语句输出第一行表头 2 表中各行数据的输出可以用下面的算法描述 for i 1 i 10 i cout i 输出行号输出第i行数据 Acout endl 准备输出下一行 例2 16 打印九九表 打印格式为 123456789112243369 991827364554637281 3 第A行需要进一步细化 由于第i行数据是一组有规律的数列 每个数的值是其所在行与列的乘积 因此输出第i行可以 for j 1 j 10 j cout setw 4 i j 4 按上述算法输出的每一行都将有九列 即打印出的是矩形表而不是下三角形表 进一步分析发现每一行的列数与所在行数相关 因此要输出三角形表 上面的循环语句需稍作修改 for j 1 j i j cout setw 4 i j 将此语句放到顶层算法的A行即可 循环的嵌套 例2 16 算法 1 输出表头 用一个循环语句即可 2 输出表体 for i 1 i 10 i cout i 输出行号输出第i行数据 Acout endl 准备输出下一行 3 A行细化 for j 1 j i j cout setw 4 i j 循环的嵌套 例2 16 在VC 平台上运行下面的程序 intmain inti j cout setw 3 setw 4 for i 1 i 10 i cout setw 4 i 输出表头 乘数 cout endl endl for i 1 i 10 i cout setw 3 i setw 4 输出行号 被乘数 for j 1 j i j cout setw 4 i j 输出表中数据 乘积 cout endl 准备输出下一行 return0 循环嵌套 例2 16 打印九九表 例2 17 打印如下图形 分析 根据按行输出的特点 语句书写如下 for i 1 i 5 i 打印第i行 Bcout endl 准备输出下一行 细化第B行 第i行可以看作两部分 先输出若干空格 接着输出若干 每行输出的 数是同的 而空格数则与所在行相关 很明显 第i行空格数为5 i 故B行细化为以下两个语句 for j 1 j 5 i j cout for j 1 j 11 j cout 2 3 4循环嵌套 例2 17 include includeusingnamespacestd intmain inti j for i 1 i 5 i 外层循环的大括号一定不能丢掉for j 1 j 5 i j cout 输出若干空格for j 1 j 11 j cout 输出若干 cout endl 准备输出下一行 return0 2 3 4循环嵌套 例2 17 break语句应用 例2 18 例2 18 给定正整数m 判定其是否为素数 分析 如果m 2 m是素数的条件是不能被2 3 取整 整除 因此可以用2 3 取整 逐个去除m 如果被其中某个数整除了 则m不是素数 否则是素数 算法属于穷举法 1 输入被测数m m 2 令整型变量k sqrt m 2 判断m是否素数 设置辅助整型变量i 使i从2开始直到k依次测试m能否整除i 若能 则不是素数 for i 2 i k i if m i 0 break 条件满足 m不是素数 停止测试 结束for语句 3 根据i是否已达到k 输出结果是否为素数 intmain intm i k cout m if m 2 coutk cout m 是素数 endl 循环提前终止表示是非素数elsecout m 不是素数 endl return0 在VC 平台上运行 改一下 使程序自动算出100以内的素数 2 6常用算法的应用实例 例2 19 直接法直接法是根据问题给出的条件直接求解 例2 19 用筛选法求100之内的所有素数 并将这些素数输出 每行输出2个数据 分析算法一穷举法 1 判断一个数是否素数 方法穷举法 2 100之内的所有素数 方法 一个个试 综上所述 得到一个循环嵌套的算法 for m 2 m 100 m 穷举法if m是素数 按要求的格式输出m k sqrt m for i 2 i k i 穷举法if m i 0 break m不是素数if i k m是素数 刚才的for是由break结束的 分析算法二筛选法 1 一个数如果是其他数的倍数 则这个数肯定不是素数 2 在由多个大于1的数组成的集合中 剔除所有的非素数 剩下的就都是素数了 综上所述 得到算法二 及所需的相应数据 1 将100之内的整数映射到一个集合 可以采用一个数组a来表示 数组元素值为各个整数 2 在数组a中 从素数2开始剔除掉新找到的素数的整数倍的元素值 置0 非素数 3 输出数组a中数组元素值非0的元素 他们都是素数 算法二第2步的细化 筛选法 for i 0 i 99 i 数组下标0 99 元素值1 100 2 1 if a i 0 continue a i 已被定为非素数 并已被筛掉2 2 将数组中所有是a i 倍数的元素置0 for j i 1 j 99 j if a j a i 0 a j 0 2 6常用算法的应用实例 例2 19 include include includeusingnamespacestd constintn 100 intmain inta n inti j for i 0 i n i a i 1 i 用数组保存整数1 100a 0 0 1不是素数 置0for i 1 i n i if a i 0 continue 该数已经置0 判断下一个for j i 1 j n j if a j a i 0 a j 0 是a i 倍数的元素置0 2 6常用算法的应用实例 例2 19 程序 intcount 0 cout 1 n 之间的素数 endl for i 0 i n i 输出所有素数if a i 0 cout setw 6 a i count if count 10 0 cout endl 每行10个 cout endl return0 运行结果 1 100之间的素数 2357111317192329313741434753596167717379838997 2 6常用算法的应用实例 例2 19 2 枚举法枚举法也称穷举法 基本思想是 在有限范围内列举所有可能的结果 找出其中符合要求的解 枚举法适合求解的问题是 可能的答案是有限个且答案是可知的 但又难以用解析法描述 这种算法通常用循环结构来完成 例2 20 世界数学史上著名的 百鸡问题 鸡翁一 值钱五 鸡母一 值钱三 鸡雏三 值钱一 百钱买百鸡 问鸡翁 母 雏各几何 分析 设鸡翁 母 雏分别为i j k 根据题意可得 i 5 j 3 k 3 1 100 i j k 100 两个方程无法解出三个变量 只能将各种可能的取值代入 其中能满足两个方程的就是所需的解 因此这是枚举算法 也叫穷举法 的应用 i j k可能的取值有哪些 分析可知 百钱最多可买鸡翁20 鸡母33 鸡雏300 算法 for i 0 i 20 i for j 0 j 33 j for k 0 k 300 k if i j k 100 这个算法使用三重循环 执行时间函数是立方阶 循环体将执行20 33 300 198000次 我们希望在算法上改进一下 如能减少一重循环 将大大缩短运行时间 2 6常用算法的应用实例 例2 20 实际上 当i j确定时 k就可由题目要求确定为100 i j 因此实际上只要用i j去测试 用钱数检测就可以了 循环体将执行 20 33 660次 算法改进为 for i 0 i 20 for j 0 j 33 if 5 i 3 j 100 i j 3 100 cout i j k 2 6常用算法的应用实例 例2 20 程序 include includeusingnamespacestd intmain inti j k cout 公鸡母鸡小鸡 endl for i 0 i 20 i for j 0 j 33 j k 100 i j if 5 i 3 j k 3 100 2 6常用算法的应用实例 例2 20 注意 穷举法采用循环 须剔除的情况 应在循环体内用用条件语句实现 不可放在循环条件中 请考虑为什么 本例是选合条件的 如去除不合条件用continue语句 改改看 程序运行结果 公鸡母鸡小鸡02575418788118112484 2 6常用算法的应用实例 例2 20 2 6常用算法的应用实例 例2 21 3 递推法 递推算法是通过问题的一个或多个已知解 用同样的方法逐个推算出其他解 如数列问题 近似计算问题等 通常也要借助于循环结构完成 例2 21 用欧基里德算法 也称辗转法 求两个整数的最大公约数 分析 假定两个整数分别为num1和num2 最大公约数应当是不超过其中较小数的一个整数 辗转法 用num1除以num2 求出余数resd 如果resd 0 则当前num2就是最大公约数 否则如果resd 0 num1 num2 num2 resd 重复以上过程 直到resd 0为止 1 设置两个整型变量num1和num2代表两个数 输入num1 num2 2 辗转法 2 1 使num1 num2 2 2 1 设置变量resd num1 num2 2 2 2 if resd 0 当前num2就是最大公约数 Else num1 num2 num2 resd 重复2 2 1和2 2 2 直到resd 0为止 2 2 do resd num1 num2 if resd 0 当前num2就是最大公约数 else num1 num2 num2 resd while resd 0 3 输出当前的num2 程序 intmain intnum1 num2 resd cout num1 num2 cout num1 和 num2 的最大公约数为 for resd num1 num2 if resd 0 break num1 num2 num2 resd cout num2 endl return0 例2 22 输入一个小于1的数x 求sinx的近似值 要求误差小于0 0001 近似计算公式如下 分析 这个近似计算可以看作一个累加过程 关键在于累加项数的确定 该求近似值的奇次多项式各项顺序改变符号 若取前n项累加和作为sin x 的近似值 则第n 1项的绝对值就是误差限 因此可以这样考虑 若公式中第一项作为累加和的初值 则第二项就是误差 如果误差不满足要求 则将该项累加到累加和上 进而用该项推出第三项 第三项又是新的累加和的误差 经过这样累加 递推 直至满足要求为止 如果用item保存第n项 则推出第n 1项的方法为 item item x x 2 n 2 n 1 2 6常用算法的应用实例 例2 22 程序 intmain constdoubleepsilon 0 0001 用epsilon保存误差doublex sinx item intn 3 sign 1 sign保存符号cout x sinx x item x x x 6 第一项作为初值 第二项为误差项while item epsilon sinx sinx item sign 将当前项累加进结果 注意符号作为因子item item x x 2 n 2 n 1 推算新的误差项sign sign 注意符号的变换n cout sin x sinx endl return0 2 6常用算法的应用实例 例2 23 例2 23 输入一个8位二进制数 将其转换为十进制数输出 分析 二进制转换为十进制只要将每位二进制数乘以该位的权然后相加 实际上属于多项式求和问题

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论