前言
平均绩点这道题其实思路很简单,但是我一直卡在了怎么获取换行,一开始由于自己对cin.get()
用法不熟悉,采用while(cin.get()!='\n')
,但是总是报错“数组或指针越界”,这上面浪费了太多时间。
题目的要点有两个,一是要把等级换算成分数,二是判断输入是否合规。自己写了大概50行代码,还调用了两个函数,题解只写了不到30行,一个主函数就搞定了,不得不说题解的逻辑很简洁。
一、“平均绩点”问题
二、我的代码
我最终是采用了模板类vector
来创建动态数组,然后通过 if(cin.get() == '\n')
实现每行数据结束的判断;通过switch
换算等级分数;然后采用cout.setf()
实现保留两位小数的输出,以上几点是自己和题解不一样的地方。
代码如下:
#include <iostream>
#include <iomanip>
#include <vector>
using namespace std;
bool gpa_judge(char g);
int gpa_to_score(char my_g);
int main() {
double avg_gpa;
char my_gpa;
vector<char> vec;
bool flag = true;
while (cin >> my_gpa) {
int sum_gpa = 0;
if(gpa_judge(my_gpa)) vec.push_back(my_gpa);
else flag = false;
if(cin.get() == '\n'){
for(int i = 0; i < vec.size(); i++){
sum_gpa += gpa_to_score(vec[i]);
avg_gpa = double(sum_gpa) / vec.size();
}
cout.setf(ios_base::fixed, ios_base::floatfield); //使用定点计数法,精度指的是小数点后面的位数,而不是总位数
cout.setf(ios_base::showpoint); //显示小数点后面的0
cout.precision(2); //使用定点计数法,显示小数点后面位数精度
if(flag == true) cout << avg_gpa << endl;
else cout << "Unknown" << endl;
vec.clear();
flag = true;
}
else;
}
if(flag == false) cout << "Unknown" << endl;
vec.clear();
return 0;
}
bool gpa_judge(char g) {
if (g == 'F' || g == 'D' || g == 'C' || g == 'B' || g == 'A'){
return true;
}
else {
return false;
}
}
int gpa_to_score(char my_g){
switch (my_g) {
case 'F': return 0;
case 'D': return 1;
case 'C': return 2;
case 'B': return 3;
case 'A': return 4;
default: break;
}
}
三、题解
题解代码大大精简的原因之一:
- 通过
if-else if-else
将等级分数换算、判断不合规输入、分数求和的过程合并到一起,10行就解决了。 - 题解判断每行数据结束的方法:
while (getline(cin, s))
表示接受一整行字符串,这样的话只需要再多判断一个空格字符就可以了。 - 适当地使用了
break
和continue
,大大简洁了代码。
#include <iostream>
#include <stdio.h>
using namespace std;
int main() {
string s;
while (getline(cin, s)) { // 接受一整行字符串
float sum = 0;
int count = 0;
int flag = 1;
for (int i = 0; i < s.size(); i++) {
if (s[i] == 'A') {sum += 4; count++;}
else if (s[i] == 'B') {sum += 3; count++;}
else if (s[i] == 'C') {sum += 2; count++;}
else if (s[i] == 'D') {sum += 1; count++;}
else if (s[i] == 'F') {sum += 0; count++;}
else if (s[i] == ' ') continue;
else {
flag = 0;
cout << "Unknown" << endl;
break;
}
}
if (flag) printf("%.2f\n", sum / count);
}
return 0;
}
四、总结
- 两种获取每行数据结束的方法:推荐使用后者
while (cin >> my_gpa) {
int sum_gpa = 0;
if(cin.get() == '\n'){
}
while (getline(cin, s)) {
}
- 保留几位小数的输出方法,也有两种,后者形式正如C语言中的一样,比较简洁方便。
#include <iomanip>
cout.setf(ios_base::fixed, ios_base::floatfield); //使用定点计数法,精度指的是小数点后面的位数,而不是总位数
cout.setf(ios_base::showpoint); //显示小数点后面的0
cout.precision(2); //使用定点计数法,显示小数点后面位数精度
cout << avg_gpa << endl;
printf("%.2f\n", sum / count)
- 模板类
vector
使用
#include <vector>
vector<char> vec;
vec.push_back(my_gpa);
vec.size();
vec.clear();