如何计算数值范围内的数组项

时间:2011-02-08 02:22:40

标签: c++

我的任务是尝试根据用户提供的一组样本值创建直方图。我已经创建了从样本值输入创建数组的程序部分,但现在我必须为直方图获取用户输入。它们给出最小值,最大值和箱数。所以,我假设bin的数量指定了直方图的数组大小。但是我很难过去如何去我的其他数组并计算特定bin的指定范围内有多少个值。我希望这是有道理的。这是我到目前为止的程序代码:

#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++)
         {
         cout << 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;
}

2 个答案:

答案 0 :(得分:1)

直方图中的每个bin通常具有相同的大小。因此,当用户给出最小值,最大值和箱数时,您可以计算每个箱的大小,从而计算每个箱的范围。每个箱子的大小

bin_size = (max-min)/#_of_bins.

现在要确定一个值进入哪个bin,计算

bin = ceil(value/bin_size)

(或者,如果你开始将你的箱子编号为0,请发言。)并增加此bin中的计数。对所有值执行此操作后,您可以打印出每个bin中的计数,这是您的直方图。

更新:如果min!= 0,则公式为:

bin = (int) (value-min)/bin_size

在这里使用强制转换b / c codemesserupper不能使用libs。 bin这里将是0索引。

答案 1 :(得分:0)

如果您知道最小值和最大值,那么任何特定值x都应该被认为是落入索引中的数组:

 (x - min) / (max - min) * #bins

这将涵盖0 ..#bin包含的范围,所以在必要时从#bins到#bins-1向下舍入。

编辑:要更加明确,并忽略对象边界,基本方法是将histoBinCounts设为0:

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];
}