Histogram Help

I am having trouble converting the numbers into a histogram output and am unsure how to even go about it. If anyone has some advice on this program,
please help.

//Headers
#include <iostream>
#include <memory>
#include <string>
#include <cstdlib>
#include <ctime>
using namespace std;

//Protypes
void arrSelectSort(int [], int);
void rowsOfTen(int [], int);
void displayResults();

int main()
{
int *pointer = nullptr;
srand(time(0));
int numbOfTests = rand() % (200 - 1 + 1) + 1;

pointer = new int[numbOfTests];

for(int i = 0; i < numbOfTests; i++)
{
pointer[i] = rand() % (99 - 55 + 1) + 55;
}

cout << "Ascending Order\n";
cout << string(30,'-') << endl;

arrSelectSort(pointer, numbOfTests);

for(int i = 0; i < numbOfTests; i++)
{
cout << pointer[i] << " ";
}

cout << endl;
cout << "Rows Of Ten\n";
cout << string(30,'-') << endl;

rowsOfTen(pointer, numbOfTests);

cout << endl;
cout << "(score intervals)\n";

cout << "55-99|";
cout << endl;
cout << "60-64|";
cout << endl;
cout << "65-69|";
cout << endl;
cout << "70-74|";
cout << endl;
cout << "80-84|";
cout << endl;
cout << "85-89|";
cout << endl;
cout << "90-94|";
cout << endl;
cout << "95-99|";
cout << endl;
cout << "|----|----|----|----|----|----|----|----|\n";
cout << "0 5 10 15 20 25 30 35 40\n";
cout << " (numbers of values in an interval)";

delete [] pointer;

return 0;
}

//void functions

void arrSelectSort(int arr[], int size)
{
int startScan, minIndex;
int minElem;
for(startScan = 0; startScan < (size - 1); startScan++)
{
minIndex = startScan;
minElem = arr[startScan];
for(int index = startScan + 1; index < size; index++)
{
if((arr[index]) < minElem)
{
minElem = arr[index];
minIndex = index;
}
}
arr[minIndex] = arr[startScan];
arr[startScan] = minElem;
}
}

void rowsOfTen(int array[], int size)
{
for(int rows = 0; rows < 10; rows++)
{
for(int i = 0; i < size; i++)
{
cout << array[i] << " ";
}
cout << endl;
}
}
if you are using the console, its easier to draw across than up and down.

after that, its fairly simple...
you have some sort of array of buckets, say its percents for test scores in 10% categories, then you have very roughly (pseudo c++):
1
2
3
4
5
6
7
8
9
10
11
12
13
int scores[10];
for(all the scores)
  scores[ somescore/10.1]++;  //10.1 forces 100 into the 99 bucket 

and then some sort of print:
for(i = 0; i < 10; i++)
{
   cout << i <<"| ";  //some sort of label for the 'columns' 
  for(int j = 0; j < scores[i]; j++)
    cout << "*";  //if j is larger you should bucketize j, eg scores[i]/10 to scale the 'graph'
cout << endl;
}


if you insist on doing it upright, you can make a 2-d array of characters (array of c-strings or string if you know it) and fill in the locations first, then print it all at the end. Its more complicated, but not out of scope if you want to try it.

just be cautious with the math. Every piece of data has to fall in a valid bucket (or be discarded if you like). You can't go out of bounds with unexpected data or carelessness (see the 10.1 above, without it, it goes out of bounds). Also need to take care with loading the buckets, what are the bounds, be precise on that.
Last edited on
Hello agirideep,

Some things that you may find useful.

PLEASE ALWAYS USE CODE TAGS (the <> formatting button), to the right of this box, when posting code.

Along with the proper indenting it makes it easier to read your code and also easier to respond to your post.

http://www.cplusplus.com/articles/jEywvCM9/
http://www.cplusplus.com/articles/z13hAqkS/

Hint: You can edit your post, highlight your code and press the <> formatting button. This will not automatically indent your code. That part is up to you.

You can use the preview button at the bottom to see how it looks.

I found the second link to be the most help.



For the start:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
//Headers
#include <iostream>
#include <iomanip>   // <--- Works with "iostream", (std::setw()).
//#include <memory>  // <--- Not used see http://www.cplusplus.com/reference/memory/
#include <string>
#include <cstdlib>
#include <ctime>

using namespace std;  // <--- Best not to use.

//Protypes
void arrSelectSort(int arr[], int size);
void rowsOfTen(int array[], int size);
void displayResults();

It is not required, but I find it is helpful to include the variable names in the prototypes.

Your srand(time(0)); works, but produces the warning ('argument': conversion from 'time_t' to 'unsigned int', possible loss of data). The more preferred method in C++ is:
srand(static_cast<unsigned int>(time(nullptr)));

I found this video worth watching: https://channel9.msdn.com/Events/GoingNative/2013/rand-Considered-Harmful

These 2 lines are the same:
1
2
    //int numbOfTests = rand() % (200 - 1 + 1) + 1;
    int numbOfTests = rand() % 200 + 1;

In your line "200 -1 + 1" is still 200. The last (+1) is so that you do not use (0)zero.

The again
1
2
//pointer[i] = rand() % (99 - 55 + 1) + 55;
pointer[i] = rand() % 100 + 1;

In your code that is a round about way of saying 100. Now if you just want the numbers 1 - 99 change the "100" to 99.

This is just a different way of writing this:
1
2
3
4
cout <<
    "\n\n"
    << std::string((30 - 11) / 2, ' ') << "Rows Of Ten\n"
    << string(30, '-') << '\n';

Making use of the new line, (\n), and the insertion operator (<<) you just have 1 "cout" statement.

In this case:
1
2
3
4
5
6
7
8
9
10
11
12
13
cout <<
    "\n(score intervals)\n"
    "55-99|\n"
    "60-64|\n"
    "65-69|\n"
    "70-74|\n"
    "80-84|\n"
    "85-89|\n"
    "90-94|\n"
    "95-99|\n"
    "|----|----|----|----|----|----|----|----|\n"
    "0 5 10 15 20 25 30 35 40\n"
    " (numbers of values in an interval)\n";

In this case all the strings in double quotes are considered as 1 big string. And if you feel the need the last line can include the "endl" function, but the new line tends to work fine to flush the buffer.

And for what it is worth:
1
2
3
    "95-99|\n"
    "     |----|----|----|----|----|----|----|----|\n"
    "     0 5 10 15 20 25 30 35 40\n"

Adding the 5 spaces in lines 2 and 3 would produce a better looking output:

55-99|
60-64|
65-69|
70-74|
80-84|
85-89|
90-94|
95-99|
     |----|----|----|----|----|----|----|----|
     0 5 10 15 20 25 30 35 40


The "arrSelectSort" does not appear to have any problems that I can see for now.

For the "rowsOfTen" your original for loops did not work. I did manage to fix your code, but the for loop at the end is much cleaner and produces a nicer looking output:

         Rows Of Ten
------------------------------
  1  1  1  1  2  2  3  3  3  3
  4  6  6  6  6  8  8  9  9  9
  9 10 10 11 12 13 14 14 14 15
 15 15 15 15 17 17 18 18 18 19
 19 21 21 21 22 23 25 25 25 25
 25 26 26 26 28 29 29 30 30 30
 31 33 33 35 35 36 37 37 38 39
 40 40 42 42 43 43 44 45 45 45
 46 46 46 47 47 47 47 48 49 50
 51 52 52 54 54 55 55 55 55 56
 56 57 58 58 58 60 61 62 62 63
 63 64 64 64 64 64 65 66 66 66
 67 67 68 68 69 69 69 70 70 71
 71 72 72 72 72 73 74 75 75 76
 76 77 77 78 78 79 79 80 80 81
 81 81 83 83 84 84 85 85 86 86
 87 88 89 89 91 92 93 93 94 95
 95 95 96 96 96 96 96 98 99 99
 99 99 99


Just some thoughts that you might useful.

Andy
Thank you, how were you able to sort the rows of 10 like that?
Topic archived. No new replies allowed.