到目前为止,我们所学的知识已经够我们干很多事了。在继续往脑子里塞新知识前,有必要总结一下现有知识都能干哪些事。把基础巩固好再向下一个目标进发。
本节和接下来几节会以实例的方式来综合运用前面所学的知识,以此达到灵活运用的目的。(也可以理解为实验课的意思)要注意,我也会在本节里面补充大量实际运用时会用上的知识点和常用写法。若要考高分或想把编程学明白的话,其重要性甚至大于前面的几课,请务必反复阅读。
合格要求:Level1 中位:看到类似代码知道它是在干什么,能够修改程序模板达到题目要求。
优秀要求:Level1 最上位:理解90%以上的代码,在不看资料的情况下能说出大致步骤,并能自己写出大致代码,以及拥有举一反三的能力。
以下是本节涉及的知识点:
• 用随机数初始化数组
• 求数组最大值最小值平均值
• 在数组里面查找元素
• 无重复地随机数初始化数组
文章目录
用随机数初始化数组
我们在做部分作业题时,或者是自己写好一个小程序想要测试时,往往会遇到需要初始化测试数据的问题。虽然此时可以手动给数组统一初始化为某个值,或者是赋予一个预先设计好的值,但是这样做会让测试变得单一,结果也总是固定的。想要别的测试,就需要再修改初始化的值。
又或是我们需要一个做出类似发牌的程序,需要把一副扑克牌(以1到54来表示,具体哪张牌对应哪个数字不重要)随机打乱随机发牌,此时也需要用到随机数来填数组。比如一个人手里拿的一副牌(假设这个人会得到18张随机发出的牌)可以用一个数组表示:{18, 7, 35, 51, 1, 16, 25, 42, 15, 8, 11, 33, 46, 53, 22, 31, 29, 49}
上述情景下,我们都需要用到用随机数初始化数组的情况。
有重复地初始化
我们首先来讨论最简单的情况,也就是单纯用随机数来填数组,不考虑数字是否可能重复。
下面我们来针对这个特定场景展开讨论:
(佟强作业题改)对于一个60人的班级,定义一个数组存放其分数。这60个人的分数由随机数生成,60人的得分相互独立,均是服从在60到100之间的均匀分布的随机整数。生成每个人的分数后,我们需要把全班的平均分算出来。最后输出平均分、最高分和最低分。
这是佟强作业题的简化版(原版比这个复杂好几倍),也是考试中程序大题里面的最基础的题。
我们不要被各种花里胡哨的要求吓住,试着把题目分解成好几步来做:
- 定义一个有60个元素的
int
数组 - 把这60个元素用60到100的随机整数填充
- 求这60个人分数的和,在循环的时候顺便找到最高分和最低分
- 把算出的和除以60得到平均分
- 按题目要求进行输出
有了这个基本思路以后,我们只需要把每一步都依次做出来就好。(虽然实际做的顺序可能和上述的不完全一样)
随机数的模板
首先,既然涉及到随机数,所以我们就要用上随机数的模板:
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
int main(){
srand(time(0));
}
始终记得随机数种子初始化一次就好。
定义数组
然后我们定义数组。我们可以直接定义一个含有60个元素的数组,但是由于一个班的同学可能会变(主要是题目上可能会变),如果变了的话,之后好些代码都要改,很不方便。所以我们把学生人数定义为一个常量。然后在此基础上定义数组。
const int N = 60;
int score[N];
这样,一旦今后需要修改学生人数,只需要把代码里面N
的值修改就可以了。
用上随机数
下面我们开始用上随机数。首先回忆我们如何需要生成一个60到100之间分布的随机整数。rand()
会为我们返回一个0到很大的数的整数,我们通过求余的方式可以获得一个更窄范围的随机数。比如rand()%41
会为我们返回0到40之间的随机整数。我们在rand()%41
的基础上加60
,就能得到60到100之间的随机整数。
也就是说,我们对数组元素的初始化的基本语句是:
score[0] = rand()%41+60;
然后针对数组的每个元素都要执行一遍随机数操作,所以我们用上for
循环:
for(int i=0; i<N; i++)
score[i] = rand()%41+60;
注意for
里面是小于符号而不是小于等于。
回顾一下
至此,用随机数初始化数组的操作已经全部做完,我们可以看看我们现在都写了些啥:
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
int main(){
const int N = 60;
int score[N];
srand(time(0));
for(int i=0; i<N; i++)
score[i] = rand()%41+60;
}
加上输出
当然由于没有任何输出语句,所以这个程序运行起来是没有任何输出的。我们可以在for
里面加上cout
语句,把每个数组元素都输出,这样我们就能看到随机数都怎么初始化我们的数组了。
参见附件知识网络1.1.1
(OneNote笔记本上),试运行看看效果。
求和
接下来我们试着对这60人的分数进行求和和找最大值最小值的操作。
求和的话,我们需要另外定义一个变量来存储其和。
int sum=0;
一定要记得把sum
初始化为0。
然后在for
循环内逐一累加即可:
for(int i=0; i<N; i++)
sum+=score[i];
找最大值和最小值
最大值和最小值的找法是相似的。大概原理就是,如果目前这个元素比已知的最大值还要大,那么就把最大值更新为这个元素。在最开始时我们拿到的数组第一个元素就是最大值和最小值的初始值(因为此时我们还没开始循环,只能先拿数组的第一个值来初始化)。
如果我们用0来初始化最小值的话,因为后面的分数总是大于60,所以这个最小值永远都是0,也就不会更新了。最大值也是一个道理。所以我们直接用数组的第一个元素来初始化。这样哪怕最大值或最小值一直没有被更新,那么它也是数组中的一个元素。(逻辑有点绞,看不明白的话请及时提问)
所以我们大概有如下代码:
int max=score[0]