我必须显示学生成绩的直方图。我把成绩存放在一个dyn中。数组,但我的目标是将它们存储在一个向量中。这是怎么回事?希望这是有道理的。
编辑:
我尝试使用矢量
void displayHistogram(int minGrade, vector<int> ptrV) {
cout << endl;
for (int i = 0; i <= minGrade; i++) {
if (ptrV[i] != 0) {
cout << "Number of " << i << "'s: " << ptrV[i] << endl;
}
}
}
void histogram() {
int minGrade = 0, grade;
const int grade_max = 100;
vector<int> ptrV(grade_max, 0);
cout << "Enter the student's grades (-1 to stop entering): \n";
do {
cin >> grade;
if (grade > minGrade) {
minGrade = grade;
}
if (grade >= 0) {
ptrV.push_back(grade);
}
} while (grade != -1);
displayHistogram(minGrade, ptrV);
}
你的基本错误是你试图强制矢量就好像它是一个原始数组。它为你做的东西,让它。例如,它知道它的大小。你不需要
void displayHistogram(int minGrade, vector<int> ptrV) {
cout << endl;
for (int i = 0; i <= minGrade; i++) {
相反,你可以使用vector::size
:
void displayHistogram(vector<int> ptrV) {
cout << endl;
for (size_t i=0; i<ptrV.size(); i++) {
(甚至更好:void displayHistogram(const vector<int>& ptrV)
表示ptrV在这里没有改变,并且每次通过使用引用调用函数时都避免复制它。)
(如果你不使用i
,因为它是等级,如果你有一个新的编译器,我建议每个循环代替。这些通常是要走的路,只是碰巧你有一个罕见的情况它不是。)
同样,你首先设置矢量的大小然后增加它,这对我来说意味着你不相信它:
vector<int> ptrV(grade_max, 0);
此时,您有一个带有一百个条目的向量,它们都是零。如果您只需要一百个条目,则无需稍后调整大小。 vector::push_back
调整它的大小。但请注意,将其设置为100意味着[100]不是有效位置,最后一个是[99],因为我们开始计数为零。您需要将其设置为101,以将零和百作为有效地址。
我将您的代码更改为:
const int grade_max = 100;
vector<int> ptrV(grade_max+1, 0); //changed it to +1 here as prtV[100] should be legal
cout << "Enter the student's grades (-1 to stop entering): \n";
while (true)
{
int grade; // put stuff in the smallest scope possible
cin >> grade;
if(grade == -1) break; // doing that here means we don't have to think about it anymore - the do while does it at last, I do it at first, handling all the special cases at the start and then assume I have the regular case.
if(grade < 0 or grade > grade_max) continue; // continue jumps to the top of the most inner loop. Note that I make sure to catch illegal but possible input.
ptrV[grade] += 1; // personal preference, I use ++ only to iterate
}
displayHistogram(ptrV);
我重新编写了结构,使用while(true)
,我认为我做的方式更直观,但会有人不同意这一点,谁也会写像
if(grade == -1)
{
break;
}
并且有一些很好的论据,主要是一个很好的练习例程,总是做大括号以避免错误。但是,我更喜欢一个衬垫来减少冗长。
一个改进也是告诉用户输入错误:
if(grade < 0 or grade > grade_max)
{
cout << "Input not in valid range. Please choose number within 0 to " << grade_max << endl;
continue;
}
现在,另一件重要的事情就是离开程序部分。去找一个class GradeHistogram
,它具有所有这些功能,被称为
GradeHistogram histogram;
histogram.take_input();
histogram.display();
但这是为了让你的代码工作。
(我的答案变得更像是在CodeReview上发现的评论,但我认为这是你需要的,而不是小修正。这是我只能推荐你的东西,顺便说一句,你的代码在CodeReview上工作。)
但我的目标是将它们存储在矢量中。
问题似乎是你已经调整了矢量大小来保存grade_max
条目。但是在填充矢量时,您使用的是push_back
。通过使用push_back
,您将在向量的末尾添加更多条目,这不是您想要做的。
解决方案是
vector<int> ptrV(grade_max, 0);
更改为此vector<int> ptrV;
并将呼叫单独留给push_back
,或者vector<int> ptrV(grade_max, 0);
,但只使用ptrV[i] = grade;
如果您想要显示的是直方图,那么最简单的方法是使用从等级到等级的std::map
。
像这样的东西:
#include <iostream>
#include <map>
int main() {
std::cout << "Enter the student's grades (-1 to stop entering): \n";
std::map<int, int> grades_map;
int input_grade = -1;
do {
cin >> input_grade;
if (input_grade > -1) {
grades_map[input_grade]++;
}
} while (input_grade != -1);
// Print histogram
for (const auto& [grade, count] : grades_map) {
std::cout << "Students with grade << grade << ": ";
for (int i = 0; i < count; ++i) {
std::cout << '*';
}
std::cout << '\n';
}
}