How to count array items within a numeric range
I am tasked with trying to create a histogram from a set of sample values that a user provides. I've created the part of the program that creates the array from sample value input, but now I must take a user input for the histogram. They give min value, max value, and number of bins. So, I'm assuming the number of bins specifies the size of the array for the histogram. But I'm stumped as to how I go to my other array and count how many values are in the specified range for a particular bin. I hope this makes sense. Here is my code for the program thus far:
#include <iostream>
using namespace std;
#define MAX_SAMPLES 100
#define MAX_BINS 20
#define DOUBLE_TOLERANCE 0.0000005
#define EXIT_VALUE -999
int promptUserAndGetChoice(); //function prototype for the menu
//for information describing sample set of data and functions that operated on //those data
class SamplingClass
{
private:
char charID; //the user enters an id for his sample set
int numbOfValues; // the number of good values the user enters
double sampleValues[MAX_SAMPLES]; //for the set of sample values.
//max is 100
public:
bool readFromKeyboard(); //prototype function
bool printToScreen();//protype function
SamplingClass(); //constructor
};
SamplingClass::SamplingClass() //initializing charID
{
charID = 0;
}
bool SamplingClass::readFromKeyboard()
{
int i = 0;
cout << "Enter character identifier for this sample:";
cin >> charID;
cout << "you entered " <<charID << "\n";
cout << "Enter all samples, then enter -999 to end:\n";
while (i < MAX_SAMPLES)
{
cin >> sampleValues[i];
if
(sampleValues[i] < EXIT_VALUE + DOUBLE_TOLERANCE && sampleValues[i] > EXIT_VALUE - DOUBLE_TOLERANCE)
{
break;
}//End if/else
i++;
}//End while
numbOfValues = i;
return true;
}
//this function checks whether charID is empty and then performs accordingly
bool SamplingClass::printToScreen()
{
if (numbOfValues == 0) ///either make a test for existance first or charID
{
cout << "ERROR: Can not print uninitialized sampling!\n";
return false;
}
else
{
cout << "Data stored for sampling with identifier " << charID << ":\n";
cout << "Total samples:" << numbOfValues << "\n";
cout << "Samples (5 samples per line):\n";
int i;
for(i=0; i<numbOfValues;i++)
{
c开发者_如何学Goout << sampleValues[i] << " ";
if (((i+1) % 5) == 0)
{
cout << endl;
}
}
cout << endl;
return true;
}
}
class HistogramClass
{
private:
double minBinValue; //specified by user
double maxBinValue; // specified by user
int numbBins; //specified by user, max of 10
int histoBinCounts[MAX_BINS];
public:
bool setupHistogram(); //prototype function
bool addDataToHistogram(SamplingClass &sampling);//protype function
bool printHistogramCounts();
bool displayHistogram();
};
bool HistogramClass::setupHistogram()
{
cout << "Enter minimum value:";
cin >> minBinValue;
cout << "Enter maximum value:";
cin >> maxBinValue;
cout << "Enter number of bins:";
cin >> numbBins;
cout << "\n";
if (numbBins <= MAX_BINS)
{cin >> numbBins;}
else
cout << "Sorry, the maximum amount of bins allowed is 20. Try again!\n";
}
//function for the menu options that display to user
int promptUserAndGetChoice()
{
cout << "1. Enter a sample set of data values\n";
cout << "2. Print the contents of the current sample set\n";
cout << "3. Reset / Provide values for setting up a histogram\n";
cout << "4. Add the contents of current sample set to histogram\n";
cout << "5. Print bin counts contained in histogram\n";
cout << "6. View the histogram in graphical form\n";
cout << "0: Exit the program\n\n";
}
int main()
{
const int enter_option = 1;
const int printContents_option = 2;
const int reset_option = 3;
const int add_option = 4;
const int printBin_option = 5;
const int viewHist_option = 6;
const int exit_option = 7;
int menuChoice;
SamplingClass sampleSet;
HistogramClass histoSet;
do
{
promptUserAndGetChoice();
cout << "Your Choice: ";
cin >> menuChoice;
if (menuChoice == 1)
{
sampleSet.readFromKeyboard();
cout << "Last Operation Successful: YES\n\n";
}
else if (menuChoice == 2)
{
sampleSet.printToScreen();
}
else if (menuChoice == 3)
{
histoSet.setupHistogram();
}
}
while (menuChoice != 7);
return 0;
}
Each bin in a histograms is typically the same size. So when the user gives you the min, max and number of bins, you can compute the size, and therefore the range, of each bin. Each bin will be of size
bin_size = (max-min)/#_of_bins.
Now to figure out which bin a value goes into, compute
bin = ceil(value/bin_size)
(Or take the floor if you start numbering your bins at 0). And increment the count in this bin. Once you do this for all values, you can print out the count in each bin and this is your histogram.
Update: If min != 0, then the formula is:
bin = (int) (value-min)/bin_size
Using the cast here b/c codemesserupper can't use libs. bin here will be 0-indexed.
If you know the min and max, then any particular value x should be considered to fall into the array at index:
(x - min) / (max - min) * #bins
This will span the range 0..#bins inclusive, so just round down from #bins to #bins-1 when necessary.
EDIT: to be more explicit, and ignoring the object boundaries, the basic approach is to 0 the histoBinCounts then:
for (int i = 0; i < numbOfValues; ++i)
{
double x = sampleValues[i];
int bin = (x - minBinValue) / (maxBinValue - minBinValue) * numbBins;
if (bin >= 0 && bin < numbBins)
++histoBinCounts[bin];
}
精彩评论