diff --git a/histogram.cpp b/histogram.cpp new file mode 100644 index 0000000..cbcd156 --- /dev/null +++ b/histogram.cpp @@ -0,0 +1,39 @@ +#include "histogram.h" +#include +#include "histogram_internal.h" +using namespace std; + +void +find_minmax(const vector& numbers, double& min, double& max) { + min = numbers[0]; + max = numbers[0]; + for (auto x : numbers) { + if (x > max) + max = x; + if (x < min) + min = x; + } +} + +vector +make_histogram(const vector& numbers, size_t bin_count) { + double max, min; + find_minmax(numbers, min, max); + vector bins(bin_count); + double bin_size = ((max - min) / bin_count); + for (size_t i = 0; i < numbers.size(); i++) { + bool found = false; + for (size_t j = 0; (j < bin_count - 1) && !found; j++) { + auto lo = min + j * bin_size; + auto hi = min + (j + 1) * bin_size; + if ((lo <= numbers[i]) && (numbers[i] < hi)) { + bins[j]++; + found = true; + } + } + if (!found) { + bins[bin_count - 1]++; + } + } + return bins; +} diff --git a/histogram.h b/histogram.h new file mode 100644 index 0000000..a86c9a3 --- /dev/null +++ b/histogram.h @@ -0,0 +1,5 @@ +#pragma once +#include + +std::vector +make_histogram(const std::vector& numbers, size_t bin_count); diff --git a/histogram_internal.h b/histogram_internal.h new file mode 100644 index 0000000..357be1f --- /dev/null +++ b/histogram_internal.h @@ -0,0 +1,6 @@ +#pragma once +#include + +void +find_minmax(const std::vector& numbers, double& min, double& max); + diff --git a/main.cpp b/main.cpp index e69de29..43cb6df 100644 --- a/main.cpp +++ b/main.cpp @@ -0,0 +1,52 @@ +#include +#include +#include +#include "histogram.h" +#include "text.h" +#include "svg.h" + +using namespace std; + + +struct Input { + vector numbers; + size_t bin_count{}; +}; + +Input +input_data() { + size_t number_count; + Input in; + cerr << "Enter number_count "; + cin >> number_count; + + in.numbers.resize(number_count); + cerr << "Enter numbers "; + for (int i = 0; i < number_count;i++) { + cin >> in.numbers[i]; + } + + cerr << "Enter bin count \n"; + cin >> in.bin_count; + + return in; +} + +void +find_minmax(const vector& numbers, double& min, double& max); + +vector +make_histogram(const vector& numbers, size_t bin_count); + +void +show_histogram_text(vector bins); + +void +show_histogram_svg(const vector& bins); + +int main() { + Input in = input_data(); + auto bins = make_histogram(in.numbers, in.bin_count); + show_histogram_svg(bins); + return 0; +} diff --git a/svg.cpp b/svg.cpp new file mode 100644 index 0000000..f980ad9 --- /dev/null +++ b/svg.cpp @@ -0,0 +1,61 @@ +#include +#include "svg.h" +#include +#include +using namespace std; + +const auto IMAGE_WIDTH = 400; +const auto IMAGE_HEIGHT = 300; +const auto TEXT_LEFT = 20; +const auto TEXT_BASELINE = 20; +const auto TEXT_WIDTH = 50; +const auto BIN_HEIGHT = 30; +const auto BLOCK_WIDTH = 10; + +void +svg_begin(double width, double height) { + cout << "\n"; + cout << "\n"; +} + +void +svg_end() { + cout << "\n"; +} + +void +svg_text(double left, double baseline, string text) { + cout << "" << text << "\n"; +} + +void svg_rect(double x, double y, double width, double height, string stroke = "black", string fill = "black") { + cout << "\n"; +} + + + +void +show_histogram_svg(const vector& bins) { + svg_begin(2000, 2000); + double top = 0; + size_t maxb = 0; + for (auto bin : bins) { + if (maxb < bin) { + maxb = bin; + } + } + int k = (IMAGE_WIDTH - TEXT_WIDTH) / maxb * BLOCK_WIDTH; + + if (k > 1) k = 1; + for (size_t bin : bins) { + const double bin_width = BLOCK_WIDTH * bin; + svg_text(TEXT_LEFT, top + TEXT_BASELINE, to_string(bin)); + svg_rect(TEXT_WIDTH, top, bin_width, BIN_HEIGHT, "black", "#87CEEB"); + top += BIN_HEIGHT; + } + svg_end(); +} diff --git a/svg.h b/svg.h new file mode 100644 index 0000000..d8f5ee9 --- /dev/null +++ b/svg.h @@ -0,0 +1,6 @@ +#pragma once +#include + +void +show_histogram_svg(const std::vector& bins); + diff --git a/text.cpp b/text.cpp new file mode 100644 index 0000000..125e83a --- /dev/null +++ b/text.cpp @@ -0,0 +1,43 @@ +#include "text.h" +#include +#include +using namespace std; +const size_t SCREEN_WIDTH = 80; +const size_t MAX_ASTERISK = SCREEN_WIDTH - 3 - 1; + +void +show_histogram_text(vector bins) { + size_t maxb = 0; + for (int i = 0;i < bins.size();i++) { + if (bins[i] > maxb) { + maxb = bins[i]; + } + } + + double k = double(MAX_ASTERISK) / maxb; + if (k > 1) { + k = 1; + + } + vector bin_graph(bins.size()); + for (size_t bin = 0; bin < bins.size(); bin++) { + bin_graph[bin] = int(double(bins[bin] * k)); + + } + for (size_t i = 0; i < bins.size(); i++) { + if (bins[i] < 100) { + cout << " "; + } + if (bins[i] < 10) { + cout << " "; + } + cout << bins[i] << '|'; + for (size_t j = 0;j < bin_graph[i];j++) { + cout << "*"; + + } + cout << endl; + + } + +} diff --git a/text.h b/text.h new file mode 100644 index 0000000..5aba06c --- /dev/null +++ b/text.h @@ -0,0 +1,4 @@ +#pragma once +#include +void +show_histogram_text(std::vector bins); \ No newline at end of file