在向量中存储动态数组

问题描述 投票:0回答:3

我必须显示学生成绩的直方图。我把成绩存放在一个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);

}
c++
3个回答
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,因为它是等级,如果你有一个新的编译器,我建议每个循环代替。这些通常是要走的路,只是碰巧你有一个罕见的情况它不是。)

同样,你首先设置矢量的大小然后增加它,这对我来说意味着你不相信它:

 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上工作。)


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;

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';
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.