1 / 68

第 3 章 C++ 中的条件与循环

第 3 章 C++ 中的条件与循环. 第 3 次见面! acm.nefu.edu.cn/C++_03.ppt. 这 2 天你们 C++ 吗?. 一夜北风寒,万里彤云厚; 长空雪乱飘,改尽江山旧。 仰面观太虚,疑是玉龙斗; 纷纷鳞甲飞,顷刻遍宇宙。 骑驴过小桥,独叹梅花瘦! 谁知道出自 ------ ? 是 李白 吗?. 上次实验课总结. 1 、注意汉字和英文的输入法; 2 、 endl 不是 end1; 3 、时时刻刻使用 C++ 的基本框架.

kane
Download Presentation

第 3 章 C++ 中的条件与循环

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 第3章 C++中的条件与循环 第3次见面! acm.nefu.edu.cn/C++_03.ppt

  2. 这2天你们C++吗? • 一夜北风寒,万里彤云厚; • 长空雪乱飘,改尽江山旧。 • 仰面观太虚,疑是玉龙斗; • 纷纷鳞甲飞,顷刻遍宇宙。 • 骑驴过小桥,独叹梅花瘦! • 谁知道出自------? • 是李白吗?

  3. 上次实验课总结 • 1、注意汉字和英文的输入法; • 2、endl 不是 end1; • 3、时时刻刻使用 C++的基本框架

  4. 上机调试的心得(授之以渔) • 1、哪行出错了 • 2、提示的字符是啥 • 3、是不是自己敲错了 • 4、缺头文件吗?was not declared in this scope • 5、结构,大括号,大小写 • 6、然后才是真的逻辑出错了

  5. 先学习C++实验的在线评测系统 • 记住网址: • acm.nefu.edu.cn

  6. acm.nefu.edu.cn

  7. 注册 register

  8. Problem 题目

  9. 如何做题 • 先看题,如 “寻找吕布”这题; • description • 三国里面吕布第一,赵云第二,典韦、关羽和马超分别是第3、第4和第5名,这是按武将的勇猛值和必杀技值的和来排名的,即武术值=勇猛值+必杀技值,下面给出这5人的勇猛值和必杀值,请你找出吕布的武术值。

  10. 寻找吕布 • input • 输入数据有多组,每组数据2行,第一行是5人的勇猛值,第二行是5人的必杀技值。勇猛值和必杀值是整数哦(32位) output • 输出吕布的武术值。

  11. sample_input • 1 2 3 4 5 • 1 2 3 4 5 • 20 21 22 45 87 • 1 100 8 99000 23 • sample_output • 10 • 99087 • hint • 吕布的勇猛值和必杀技值都是第一的!

  12. #include <iostream> • using namespace std; • int main() • { • int data[6],inp[6];//定义变量 • int ym,bs;//勇猛值 必杀值的变量 • while(cin>>data[1]>>data[2]>>data[3]>>data[4]>>data[5])// 注意 • { • ym=0,bs=0; //这句很重要,必须先清0 • for(int i=1;i<=5;i++) if (ym<data[i]) ym=data[i]; • cin>>inp[1]>>inp[2]>>inp[3]>>inp[4]>>inp[5]; • for(int i=1;i<=5;i++) if (bs<inp[i]) bs=inp[i]; • cout<<ym+bs<<endl; • } • //cout << “Hello world!” << endl; 记得要注视掉啊 • return 0; • }

  13. 再看服务器里的数据 • data.in 输入文件 data.out 输出文件 • 1 2 3 4 5 10 • 1 2 3 4 5 99087 • 20 21 22 45 87 16 • 1 100 8 99000 23 • 1 2 6 8 9 • 7 4 3 2 1 你不知道服务器的数据是啥!

  14. 提交答案 :题目下面submit

  15. 看评判结果

  16. 欢迎有敏感的人加入ACM • 数学好 • 算法好(可以培养) • 能吃苦就行

  17. 条件语句 • if • switch • 和C 语言一样,基本知识不变 • 通过实例来讲解

  18. 条件表达式 • ?:运算符 :问号冒号运算符 • 作用:更加简练的用来表达条件执行的方式 • 形式 : (条件) ? 表达式1 : 表达式2 • 执行过程:首先计算条件值。如果条件结果为true,则计算表达式1的值,并将它作为整个表达式的值。如果条件结果为false,则整个表达式的值为表达式2的值。

  19. 实例 • 例如将x和y中值较大的一个赋值给max,可以用下列语句: max = (x > y) ? x : y; • ?:运算符用于输出。例如,想输出一个布尔变量flag的值,如果直接用 cout << flag; 那么当flag为“真”时,输出为1;当flag为“假”时,输出为0。 如果我们想让flag为“真”时输出true,为“假”时输出false,可以用if 语句 if (flag) cout << “true”; else cout << “false”; 看上去太罗嗦。但如果用?:运算符只需要一行 cout << ( flag ? "true" : "false" ) << endl;

  20. 判断闰年的程序 #include <iostream> using namespace std; int main() { int year; bool result; cout << "请输入所要验证的年份:"; cin >> year; result = (year % 4 == 0 && year % 100 !=0)|| year % 400 == 0; if (result) cout << year << "是闰年" << endl; else cout << year << "不是闰年" << endl; return 0; }

  21. 计算机自动出四则运算计算题 要求自动出0 - 9之间的四则运算题,并批改结果 生成题目 Switch(题目类型) { case 加法:显示题目,输入和的值,判断正确与否 case 减法:显示题目,输入差的值,判断正确与否 case 乘法:显示题目,输入积的值,判断正确与否 case 除法:显示题目,输入商和余数的值,判断正确与否 }

  22. 关键问题 • 如何让程序每次执行的时候都出不同的题目? • 随机数生成器rand():能随机生成0到RAND_MAX之间的整型数 • 将生成的随机数映射到0 - 9之间: • Rand() % 10 • rand() * 10 / (RAND_MAX + 1)。 • 运算符的生成:用编码0 - 3表示四个运算符。因此题目的生成就是生成0 - 3之间的随机数。

  23. 12348 rand() 种子 12348 随机数的种子 • 计算机产生的随机数称为伪随机数,它是根据一个算法计算出来的。 • 系统为每个程序、每次执行指定的随机数的种子都是相同的,因此程序每次执行生成的随机数序列都是相同的。

  24. 改变随机数的种子 • 设置种子的函数srand : srand (种子) • 如何让程序每次执行时选择的种子都不一样呢? • 选择系统时间为种子:time(NULL) 取当前的系统时间。

  25. 自动出题程序 #include <cstdlib> //包含伪随机数生成函数 #include <ctime> //包含取系统时间的函数 #include <iostream> using namespace std; int main() { int num1, num2, op, result1, result2; //num1,num2:操作数,op:运算符,result1,result2: 结果 srand(time(NULL)); //随机数种子初始化 num1=rand() * 10 / (RAND_MAX + 1); // 生成运算数 RAND_MAX=32767 num2=rand() * 10 / (RAND_MAX + 1); //生成运算数 op=rand() * 4 / (RAND_MAX + 1); // 生成运算符 0--+, 1-- -, 2--*,3-- /

  26. switch (op) {case 0: cout << num1 << "+" << num2 << "= ?" ; cin >> result1; if (num1 + num2 == result1) cout << "you are right\n"; else cout << "you are wrong\n"; break; case 1: cout << num1 << "-" << num2 << "= ?" ; cin >> result1; if (num1 - num2 == result1) cout << "you are right\n"; else cout << "you are wrong\n"; break; case 2: cout << num1 << "*" << num2 << "= ?" ; cin >> result1; if (num1 * num2 == result1) cout << "you are right\n"; else cout << "you are wrong\n"; break;

  27. case 3: cout << num1 << "/" << num2 << "= ?" ; cin >> result1; cout << “余数为 = ?"; cin >> result2; if ((num1 / num2 == result1) && (num1 % num2 == result2)) cout << "you are right\n"; else cout << "you are wrong\n"; break; } return 0; }

  28. 该程序的缺陷 • 每次执行只能出一道题 • 减法可能出现负值 • 除法可能出现除0 • 结果太单调

  29. 再看循环结构 • For 基本的习惯 • While 用处 • Do while

  30. For循环实例 • 某班级有100个学生,设计一程序统计该班级某门考试成绩中的最高分、最低分和平均分。 • 方案一:先输入100个整型数,保存在各自的变量中。然后依次检查这100个数,找出最大的和最小的。在找的过程中顺便可以把所有的数都加起来。最后将总和除100就得到了平均值。

  31. 方案一的缺陷 • 需要定义100个变量 • 需要输入100个变量的值 • 从100个变量中找出最大者,需要100个if 语句 • 从100个变量中找出最小者,需要100个if 语句 • 将这100个变量加起来需要一个长长的算术表达式

  32. 方案二 • 每个学生的分数在处理过后就没用了,为此,可以用一个变量保存当前正在处理的分数 • 每次输入分数的同时将它们加起来:70加40等于110,110加80等于190……。并记住最低分的和最高分的值。上述过程重复100次。

  33. 方案二的实现 • 定义: int value, total,max, min; • 当输入每个数值时必须执行下面的步骤,这可以用for循环实现 • 请求用户输入一个整数值,将它存储在变量value中。 • 将value加入到保存当前和的变量total中。 • 如果value大于max,将value存于max。 • 如果value小于min,将value存于min。

  34. #include<iostream> using namespace std; int main() { int value, total, max, min, i;//value:当前输入数据,i为循环变量 total = 0; max = 0; min = 100; //变量的初始化 for (i=1; i<=100; ++i) { cout << "\n请输入第" << i << "个人的成绩:"; cin >> value; total += value; if (value > max) max = value; if (value < min) min = value; } cout << "\n最高分:" << max << endl; cout << "最低分:" << min << endl; cout << "平均分:" << total / 100 << endl; return 0; } 注意缩进

  35. a b For循环实例 • 求函数 在区间[a, b]之间的定积分 • 实现思想:函数与x轴围成的区域的面积。定积分可以通过将这块面积分解成一连串的小矩形,计算各小矩形的面积的和而得到

  36. int main() { double a, b, dlt, integral = 0; cout << "请输入定积分的区间:" ; cin >> a >> b; cout << "请输入小矩形的宽度:" ; cin >> dlt; for (double x = a + dlt / 2; x < b; x += dlt) integral += (x * x + 5 * x + 1) * dlt; cout << "积分值为:" << integral << endl; return 0; }

  37. eg 2.求 时结束。 ex=0; p = 1; while (p>0.000001) { ex += p; 计算新的p; } 问题: 如何计算p?计算第i个p,需要两个i次的循环。第一个循环计算xi,第二个循环计算i! 解决方案: 从前一项计算后一项。如果p是第i项的值,则第i+1项的值为 p*x/(i+1)

  38. int main() {double ex, x, p;//ex存储ex的值,p保存当前项的值 int i; cout << "请输入x:"; cin >> x; ex=0; p=1; i=0; while (p > 1e-6){ ex += p; ++i; p = p * x / i; } cout << "e的" << x << "次方等于:" << ex << endl; return 0; }

  39. 枚举法 • 对所有可能的情况一种一种去尝试,直到找到正确的答案。 • 枚举法的实现基础是循环。

  40. 枚举法实例一 • 用50元钱买了三种水果。各种水果加起来一共100个。西瓜5元一个,苹果1元一个,桔子1元3个,设计一程序输出每种水果各买了几个 • 它有两个约束条件: • 第一是三种水果一共100个; • 第二是三种水果一共花了50元 • 可以按一个约束条件列出所有可行的情况,然后对每个可能解检查它是否满足第二个约束条件 。也可以用第二个约束条件列出所有情况,然后对每个可能解检查它是否满足第一个约束条件 。

  41. #include <iostream> using namespace std; int main() { int mellon, apple, orange; //分别表示西瓜数、苹果数和桔子数 for (mellon=1; mellon<10; ++mellon) // 对每种可能的西瓜数 for ( apple=1; apple < 50 - 5 * mellon; ++apple) { //当西瓜数给定后可能的苹果数 orange = 3*(50-5*mellon-apple); // 剩下的钱全买了桔子 if (mellon+apple+orange == 100){ // 三种水果数之和是否为100 cout << "mellon:" << mellon << ' '; cout << "apple:" << apple << ' '; cout << "orange:" << orange << endl; } } return 0; }

  42. 执行结果 Mellon:1 apple:18 orange:81 Mellon:2 apple:11 orange:87 Mellon:3 apple:4 orange:93

  43. 实例二 — 四大湖问题 上地理课时,四个学生回答我国四大湖的大小时分别说: 甲:洞庭最大,洪泽最小,鄱阳第三 乙:洪泽最大,洞庭最小,鄱阳第二,太湖第三 丙:洪泽最小,洞庭第三 丁:鄱阳最大,太湖最小,洪泽第二,洞庭第三 对于每个湖的大小,每个人仅答对一个,设计一程序让计算机通过这些信息去判别四个湖的大小。

  44. 解题思路 • 如果用a,b,c,d分别表示四个湖的排序。a表示洞庭湖,b表示洪泽湖,c表示鄱阳湖,d表示太湖。我们可以假设:洞庭最大,洪泽第二,鄱阳第三,太湖第四,然后检查每位同学是否都讲对了一个。如果不是,再尝试下一种情况:洞庭最大,洪泽第二,鄱阳第四,太湖第三,再检查每位同学是否都讲对了一个。尝试所有可能的情况,直到满足每位同学都讲对一个为止。

  45. 枚举法—续 • 为了尝试所有情况,我们需要假设洞庭湖可能是最大,也可能是第二、第三或第四。因此,a的值可能从1变到4。同样,b, c ,d的值也都可能从1变到4。为此,我们需要一个控制结构,使a, b, c, d的值能自动从1变到4。这种结构就是循环结构。

  46. 四大湖排列问题的解 问题:效率差 解决方法:一旦找到答案就应该结束 main() { int a, b, c, d; for (a=1; a<=4; ++a) for (b=1; b<=4; ++b) if ( a == b) continue; else for (c=1; c<=4; ++c) if (c==a||c==b) continue; else {d=10 – a – b - c; if (((a==1)+(b==4)+(c==3))==1 &&((b==1)+(a==4)+(c==2)+(d==3))==1 &&((b==4)+(a==3))==1 &&((c==1)+(d==4)+(b==2)+(a==3))==1) cout << a << b << c << d; } }

  47. 改进版1: main() { int a, b, c, d; bool flag = false; for (a=1; a<=4; ++a) { for (b=1; b<=4; ++b) { if ( a == b) continue; else for (c=1; c<=4; ++c) if (c==a||c==b) continue; else {d=10 – a – b - c; if (((a==1)+(b==4)+(c==3))==1 //注意 &&((b==1)+(a==4)+(c==2)+(d==3))==1 &&((b==4)+(a==3))==1 &&((c==1)+(d==4)+(b==2)+(a==3))==1) { cout << a << b << c << d; flag = true; break; } } if (flag) break;} if (flag) break;} } //break 只能退出当前循环体 程序不够简练

  48. 改进版2 main() { int a, b, c, d; bool flag = false; for (a=1; a<=4 && !flag; ++a) { for (b=1; b<=4 && !flag; ++b) { if ( a == b) continue; else for (c=1; c<=4 ; ++c) if (c==a||c==b) continue; else {d=10 – a – b - c; if (((a==1)+(b==4)+(c==3))==1 &&((b==1)+(a==4)+(c==2)+(d==3))==1 &&((b==4)+(a==3))==1 &&((c==1)+(d==4)+(b==2)+(a==3))==1) { cout << a << b << c << d; flag = true; break; } } } } }

  49. 列出ABC三个字母的全排列 • 解题思路: • 让第一个位置的值从A依次变到C • 让第一个位置的值从A依次变到C • 让第一个位置的值从A依次变到C • 注意三个位置的值不能相同 • 可以用一个三层的嵌套循环实现,循环变量是字符类型

  50. int main() { char c1, c2, c3; for (c1 = ‘A’; c1 <= ‘C’; ++c1) for (c2 = ‘A’; c2 <= ‘C’; ++c2) if (c1 == c2) continue; else for (c3 = ‘A’; c3 <= ‘C’; ++c3) if ((c3 == c1 || c3 == c2)) continue; else cout << c1 << c2 << c3 << endl; }

More Related