c++题解:循环(1)——成绩分析
题目描述
云云最近刚结束了他的期中考试,为了在之后的期末考试中取得更好的成绩,他决定对自己期中考试的所有科目的分数进行分析,从中找出其中的最大值,最小值和平均分(注意:他所有科目的分数均为整数,且平均分为整除的商),但是他的计算能力很差,聪明的你能帮助他解决这个问题吗?
输入格式
第一行一个正整数𝑁(𝑁≤100)N(N≤100); 第二行有N个用空格隔开的整数𝑇𝑖(1≤𝑖≤𝑁,0≤𝑇𝑖≤1⋅107)Ti(1≤i≤N,0≤Ti≤1⋅107)
输出格式
三个有空格隔开的整数,分别为最大值、最小值和平均值,其中平均值为整除的商。
样例
输入数据 1
5
1 2 3 5 4
输出数据 1
5 1 3
错误解法:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
cin >> n;
int a[n]; //错误1
int shu;
int sum = 0;
//数组赋值
while(n--)
{
int i = 0;
cin >> shu;
a[i] = shu;
sum += a[i];
i++;
}
//计算平均数
int average;
average = sum / n; //错误2
//找出最小值
int min = a[0];
for(int i = 0; i < n; i++) //错误3
{
if(a[i] > a[i + 1]) //错误4
{
min = a[i +1];
}
}
//找出最大值
int max = a[0];
for(int i =0; i< n; i++)
{
if(a[i] <a[i +1])
{
max = a[i +1];
}
}
printf("%d %d %d", average, min, max);
return 0;
}
错误分析:
错误1:c++中不支持变长数组的用法。
改正:此处应该使用动态内存分配。
错误2:n在while循环里已经改变了原来的值。while循环结束后n的值已经变成了0。
改正:此处使用for循环即可。
错误3:数组越界访问。当i = n-1时,a[i +1]就会访问数组之外的内存,造成数组越界。
改正:循环条件为i < n-1
错误4:找出最小和最大值的条件判断有误。a[i]<a[i+1]只是进行相邻两数之间的比较,对于正序数列而言,可以找出最小最大值,而对于一般数列就会出错。
改正:判断条件改为min>a[i+1]和max<a[i+1]
正确代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
cin >> n;
int*a = new int[n]; //动态内存分配
int shu;
int sum = 0;
for(int i=0; i< n; i++)
{
cin >> shu;
a[i] = shu;
sum += a[i];
}
int average;
average = sum / n;
int min = a[0];
for(int i = 0; i < n - 1; i++)
{
if(min > a[i + 1])
{
min = a[i +1];
}
}
int max = a[0];
for(int i =0; i< n - 1; i++)
{
if(max <a[i +1])
{
max = a[i +1];
}
}
printf("%d %d %d", average, min, max);
delete[] a; //释放动态分配的内存
return 0;
}
这个代码还是有些繁琐,因为找最小最大数和求数列和都要用到for循环,而且循环条件基本可以一致,所以我们可以都写在一个for循环里。
让我们来看看化简后的代码。
错误代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
cin >> n;
int* a = new int[n];
for(int i= 0; i< n; i++)
{
cin >> a[i];
}
int max,min;
int sum = 0;
for(int i =0; i<n; i++)
{
max = a[0]; //错误1:每次循环都重置max为a[0]
if(max < a[i])
{
max = a[i];
}
int min = a[0]; //错误2:用Int创建了新的局部变量,只在循环内有效
min = a[0];
if(min > a[i])
{
min = a[i];
}
sum += a[i];
}
int average;
average = sum / n;
printf("%d %d %d", max, min, average);
delete[] a;
return 0;
}
错误分析:
错误1:循环内用到的变量,如果需要再循环内发生值的改变,应该在循环体外进行赋值。
错误2:循环体内用用数据类型+变量名,就是构建了一个新的局部变量,在循环体内有效,在循环体外不能识别。
正确代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
cin >> n;
int* a = new int[n];
for(int i= 0; i< n; i++)
{
cin >> a[i];
}
int max = a[0];
int min = a[0];
int sum = 0;
for(int i =0; i<n; i++)
{
if(max < a[i])
{
max = a[i];
}
if(min > a[i])
{
min = a[i];
}
sum += a[i];
}
int average;
average = sum / n;
printf("%d %d %d", max, min, average);
delete[] a;
return 0;
}
拓展
题目中说了输入一个正整数,如果题目没有说,需要检查数组是否是空数组,或者使用初始化极值。
#include<climits>
int min = INT_MAX;
int max = INT_MIN;
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
cin >> n;
int* a = new int[n];
for(int i= 0; i< n; i++)
{
cin >> a[i];
}
int max=INT_MIN;
int min=INT_MAX;
int sum = 0;
for(int i =0; i<n; i++)
{
if(max < a[i])
{
max = a[i];
}
if(min > a[i])
{
min = a[i];
}
sum += a[i];
}
int average;
average = sum / n;
printf("%d %d %d", max, min, average);
delete[] a;
return 0;
}
初始化极值会更安全
原理:
-
INT_MIN是 C++ 中int类型能表示的最小值(通常是 -2,147,483,648) -
INT_MAX是 C++ 中int类型能表示的最大值(通常是 2,147,483,647)
为什么这样有效?
-
任何实际的分数(≥0)都 大于
INT_MIN,所以第一个分数一定会更新max -
任何实际的分数(≤10,000,000)都 小于
INT_MAX,所以第一个分数一定会更新 min
更多推荐



所有评论(0)