У вас две проблемы. Очевидно, вы хотите построить гистограмму и хотите визуализировать эту гистограмму.
Гистограмма
Один из подходов к построению гистограммы требует предварительного указания количества бинов (однородной ширины), минимального значения (включительно) и максимального значения (не включительно). Затем вы можете вычислить индекс корзины, которой должен быть присвоен каждый элемент.
Вот (непроверенный) пример:
const int nbins = 10;
const double minval = .0, maxval = 100.;
std::vector<int> bins(nbins, 0);
for (double x; infile >> x; ) {
if (x >= minval && x < maxval) {
// note that integer rounding is probably towards zero, not towards -inf
int idx = floor((x-minval)/(maxval-minval)*nbins);
bins[idx]++;
}
else {
// handle outlier
}
}
Визуализация
Подход, описанный в этом ответе , представляется целесообразным. Для большого количества бинов вам может потребоваться некоторая процедура нормализации, то есть масштабирование значений до диапазона [0,10]
или аналогичного.
Посмотрите на этот (непроверенный) пример:
const int chart_height = 10;
const int max_count = *std::max_element(bins.begin(), bins.end());
for (int current_height = chart_height; current_height > 0; --current_height) {
for (int count : bins) {
const int bar_height = (count*chart_height)/max_count;
if (bar_height < current_height)
std::cout << " "; // we're still above the bar
else if (bar_height == current_height)
std::cout << " _ "; // reached the top of the bar
else // bar_height > current_height
std::cout << " | | "; // now the rest of the bar ...
}
std::cout << '\n';
}
С помощью небольшого количества магии и трюков вы также можете расширить ее для создания пограничной гибкой визуализации, такой как this :
11 | _______ _______
| | | | |
| | | | |
| | | | |
| | | | | _______
5 | | | | | | |
| | | | | | |
| | | | | | | _______
| _______ | | | | | | _______ | |
| | | | | | | | | | | | |
+------v----------v----------v----------v----------v----------v-----
3.7 - 4.3 4.3 - 4.9 4.9 - 5.6 5.6 - 6.2 6.2 - 6.8 6.8 - 7.4