Not Getting Correct Output for Histogram

For this assignment, I need to get grades (0 < grades < 100) and store them into a vector. After, I need to see how many times a certain number was entered. Then, I need to store the elements in the vector into a dynamic array. Then, I need to output the dynamic array. The problem I am having is it's not outputting the correct numbers on certain occasions.
Here is the code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#include<iostream>
#include<vector>
#include<algorithm>

using namespace std;

void getGrades(vector<int>&);
void copyVector(vector<int>, vector<int>&);
void deleteDuplicates(vector<int>&);
void getCount(vector<int>, vector<int>, vector<int>&);
void vectorToDArray(int [], int, vector<int>);
void printArray(int [], int [], int);

typedef int* IntPtr;

int main()
{
	vector<int> grades, gradesCopy, uniqueCount;

	getGrades(grades);
	sort(grades.begin(), grades.end()); //#include<algorithm>
	copyVector(grades, gradesCopy);
	deleteDuplicates(grades);
	getCount(grades, gradesCopy, uniqueCount);

	int size = uniqueCount.size();
	IntPtr gradeArray, countArray;
	gradeArray = new int [size];
	countArray = new int [size];

	vectorToDArray(gradeArray, size, grades);
	vectorToDArray(countArray, size, uniqueCount);
	printArray(gradeArray, countArray, size);

	delete [] gradeArray;
	delete [] countArray;

	return 0;
}

//will prompt the user in a do-while loop to get the grades and will end when -1 is entered
//push_back will be used to store the grades into a created vector
void getGrades(vector<int>& grades) {

	int grade;

	cout << "**************************************************************************************" << endl;
	cout << endl;
	cout << "               WELCOME TO THE HISTOGRAM OF STUDENT GRADES MAKER THINGY" << endl;
	cout << endl;
	cout << "**************************************************************************************" << endl;
	cout << endl;
	cout << "Please enter the student's grades. When you have entered a single grade, press enter. " << endl;
	cout << "When finished entering all grades, type in '-1' and then press enter. " << endl;
	cout << endl;
	do {
		cin >> grade;
		if (grade != -1) {
			grades.push_back(grade);
		}
	} while (grade != -1);
}

//gets the grades with the original vectors and will use push_back
//to be put and copied into another vector
void copyVector(vector<int> grades, vector<int>& gradesCopy) {
	for (int i = 0; i < grades.size(); i++) {
		gradesCopy.push_back(grades[i]);
	}
}

//deletes the duplicates in the first vector
//needed to compare to second vector
void deleteDuplicates(vector<int>& grades) {
	for (int i = 0; i < grades.size(); i++) {
		for (int j = i + 1; j < grades.size(); j++) {
			if (grades[i] == grades[j]) {
				grades.erase(grades.begin() + j);
			}
		}
	}
}

//compares the two vectors and when one equals the other the count goes up
//count is then pushed back to another vector to hold the count for each number
void getCount(vector<int> g1, vector<int> g2, vector<int>& c) {
	int count = 0;
	for (int i = 0; i < g1.size(); i++) {
		for (int j = 0; j < g2.size(); j++) {
			if (g1[i] == g2[j]) {
				count++;
			}
		}
		c.push_back(count);
		count -= count;
	}
}

void vectorToDArray(int a[], int size, vector<int> v) {
	for (int i = 0; i < size; i++) {
		a[i] = v[i];
	}
}

void printArray(int a[], int b[], int size) {
	for (int i = 0; i < (size - 1); i++) {
		cout << "Number of " << a[i] << "'s : " << b[i] << endl;
	}
}


When I enter "4, 10, 20, 30, 20, 30, 30", I get:


Number of 4's: 1
Number of 10's: 1
Number of 20's: 2
Number of 30's: 3


but when my professor graded it, he entered in "50, 50, 40, 30, 30, 40, 40, -1".
His output was:


Number of 30's: 2
Number of 40's: 3
Number of 40's: 3


So, I was wondering why it worked for the first input, but for the second one it didn't output the number of 50's and did the number of 40's twice.
Any help would be greatly appreciated!
Last edited on
Your first error is in deleteDuplicates. When you delete a value, you don't want to increment j. Instead, you want to check the value at position j again because it's a different value after you erase:
1
2
3
4
5
6
7
                for (size_t j = i + 1; j < grades.size();) {  // no increment here
                        if (grades[i] == grades[j]) {
                                grades.erase(grades.begin() + j);
                        } else {
                            ++j;
                        }
                }

The second bug is in printArray. You aren't printing the last value. Line 106 should be
for (int i = 0; i < size; i++) {

I suspect that at some point, you had printArray() correct and when you ran it with your first input you got:
Number of 4's : 1
Number of 10's : 1
Number of 20's : 2
Number of 30's : 3
Number of 30's : 3

Seeing the 3 lines for Number of 30's, you probably assumed that your printing code was wrong, subtracted 1 from size and everything looked good. Instead, you actually masked the other problem ion deleteDuplicates(). I like to call this "cooperating bugs." Two (or more) bugs in the code that work together to produce seemingly correct results. When you fix one bug, the results are wrong(!) You have to fix them both.

BTW, you don't need copyVector. You could have simply said gradesCopy = grades;
@dhayden thank you so much! That fixed my problem and you were correct with my printArray problem. Thanks again.
The moral of this story is: don't just randomly do stuff until your program looks like it's working.

When something's not working right, you should take the effort to understand why. Then you'll know the right thing to do to fix it, rather than making things worse by adding a second bug to the first one.
+1 MikeyBoy.

In this case, I found the bug by adding a function to print a vector<int> and printed the various intermediate results. This sort of test code is really useful.
Topic archived. No new replies allowed.