2011-02-08 2 views
0

Мне поручено создать гистограмму из набора значений образцов, которые предоставляет пользователь. Я создал часть программы, которая создает массив из ввода значения образца, но теперь я должен взять пользовательский ввод для гистограммы. Они дают минимальное значение, максимальное значение и количество ящиков. Итак, я предполагаю, что количество ячеек задает размер массива для гистограммы. Но я в тупике о том, как я иду к другому массиву и подсчитываю, сколько значений указано в указанном диапазоне для определенного бина. Я надеюсь в этом есть смысл. Вот мой код программы до сих пор:Как подсчитать элементы массива в числовом диапазоне

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

ответ

0

Если вы знаете мин и макс, то любое конкретное значение х следует считать падать в массив с индексом:

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

Это будет span range 0 .. # bins включительно, поэтому просто округлите от #bins до # bins-1, когда это необходимо.

EDIT: чтобы быть более явным, и игнорируя границы объекта, основным подходом является 0, то histoBinCounts:

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

Хммм - Я не уверен, что я следую. Массив набора выборки уже создан к тому моменту, когда пользователь вводит min, max и количество бункеров. извините, я новичок новичок, поэтому даже не знаю, задаю ли я правильные вопросы. Кстати, большое спасибо за быстрый ответ! Я думаю, что создаю новый массив ящиков с размерами, которые вводит пользователь. Затем в каждом слоте массива идет подсчет количества вещей в первом массиве, которые попадают в диапазон каждого нового слота для буфера. Имеет ли это смысл? – codemesserupper

+0

Хорошо, я собираюсь работать с этим и сообщить вам, как это происходит. Спасибо всем! – codemesserupper

+0

@codemesserupper: конечно ... надеюсь, что все идет хорошо. –

1

Каждый бин в гистограмм, как правило, такой же размер. Поэтому, когда пользователь дает вам мин, макс и количество ящиков, вы можете вычислить размер и, следовательно, диапазон каждого бункера. Каждый бункер будет иметь размер

bin_size = (max-min)/#_of_bins. 

Теперь чтобы выяснить, какие бен значение переходит в вычислите

bin = ceil(value/bin_size) 

(Или взять слово, если начать нумерацию ваших бункеров 0). И увеличивайте счет в этом бункере. Как только вы сделаете это для всех значений, вы можете распечатать счет в каждом бункере, и это ваша гистограмма.

Update: Если мин = 0, то формула:

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

Использование литых здесь б/с codemesserupper не может использовать LIBS. bin здесь будет 0-индексированным.

+0

Что такое потолок? Это новая переменная? – codemesserupper

+0

@codemesserupper: Это функция в '' или' ', которая принимает наименьшее целое число выше или равно его аргументу. Функция 'floor' делает противоположное: наибольшее целое число ниже или равно аргументу. –

+0

А, хорошо, это проблема в том, что мне не разрешено полагаться на библиотеки для этого. :( – codemesserupper

Смежные вопросы