在向量中存储动态数组

时间:2019-03-03 07:30:52

标签: c++

我必须显示学生成绩的直方图。我已将成绩存储在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);

}

3 个答案:

答案 0 :(得分:1)

  

但是我的目标是将它们存储在向量中。

问题似乎是您已经确定矢量的大小以容纳grade_max个条目。但是,在填充矢量时,您正在使用push_back。通过使用push_back,您将在向量的末尾添加更多条目,这不是您想要执行的操作。

解决方案是

  1. 将此vector<int> ptrV(grade_max, 0);更改为此vector<int> ptrV;并仅留下对push_back的呼叫,或者
  2. 保留vector<int> ptrV(grade_max, 0);,而只使用ptrV[i] = grade;

答案 1 :(得分:1)

您的基本错误是,您试图将向量强制为原始数组。它为您做东西,让它。例如,它知道尺寸。你不需要

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,因为它是年级,并且如果您使用的是较新的编译器,则建议为每个循环使用a。通常是这样做的方式,您有一种罕见的情况并非如此。)

同样,您首先设置向量的大小,然后再增加它,对我而言,这意味着您不信任它:

 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上运行。)

答案 2 :(得分:0)

如果要显示的是直方图,那么最简单的方法是使用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';
    }
}