From 32cbe0c38c5b245033253e9917f622ed3a887f42 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 20 Sep 2020 08:14:05 +0700 Subject: [PATCH] [3sem] dsaa02 done --- 3sem/data structures and algos/02/program.cpp | 190 ++++++++++++++++++ 1 file changed, 190 insertions(+) create mode 100644 3sem/data structures and algos/02/program.cpp diff --git a/3sem/data structures and algos/02/program.cpp b/3sem/data structures and algos/02/program.cpp new file mode 100644 index 0000000..1f2a704 --- /dev/null +++ b/3sem/data structures and algos/02/program.cpp @@ -0,0 +1,190 @@ +// dsaa_02.cpp +// Горбацевич Андрей +#include +#include +#include +#include +#include +#include + +#ifdef DEBUG +#define printf_d printf +#else +#define printf_d(...) +#endif + +class DynIntArr { // ngl, can be done better +private: + int *container; + int _size = 0; + int _capacity; + + void _resize(int new_size) { + int *new_container = new int [new_size]; + for (int i = 0; i < this->_size; i++) { + *(new_container + i) = *(this->container + i); + } + std::swap(this->container, new_container); + delete [] new_container; + + this->_capacity = new_size; + } +public: + explicit DynIntArr(int initial_size=8) { + this->_capacity = initial_size; + this->container = new int [this->_capacity]{0}; + } + ~DynIntArr() { + if (this->container != nullptr) { + delete [] this->container; + } + } + + int &at(int pos) { + if (pos < 0 || pos > this->_capacity) { + throw std::runtime_error("Illegal array access"); + } + return *(this->container + pos); + } + + void add(int val) { + if (this->_size+1 > this->_capacity) { + this->_resize(this->_capacity*2); + } + this->at(this->_size++) = val; + } + + int size() const { // NOLINT(modernize-use-nodiscard) + return this->_size; + } + + int capacity() const { // NOLINT(modernize-use-nodiscard) + return this->_capacity; + } +}; + +inline void time_passed(std::chrono::system_clock::time_point start, double &holder) { + auto stop = std::chrono::high_resolution_clock::now(); + auto duration = std::chrono::duration_cast(stop - start); + holder = duration.count(); +} + + +void algo_01(DynIntArr &cont); // algo with my container +void algo_02(std::vector &cont); // algo with stl's vector + + +// let's assume we are not including reading of data into algo's time +// 'cause it can at worst be O(inf) +int main() { + int reserve = 50; + DynIntArr dyn_arr(reserve); + std::vector vec_int; + vec_int.reserve(reserve); + + int N = 0; + std::cout << "N="; + std::cin >> N; + for (int i = 0; i < N; i++) { + int num = 0; + std::cin >> num; + dyn_arr.add(num); + vec_int.push_back(num); + } + + double fft, sft = fft = 0; + + if (N <= 2) { // Well, even if smth. is missed there is no way to determine + goto endo; + } + + { // algo with my container + auto start = std::chrono::high_resolution_clock::now(); + algo_01(dyn_arr); + time_passed(start, fft); + } + { // algo with stl's vector + auto start = std::chrono::high_resolution_clock::now(); + algo_02(vec_int); + time_passed(start, sft); + } + { // let's check integrity of content + assert(dyn_arr.size() == vec_int.size()); + for (int i = 0; i < dyn_arr.size(); i++) { + assert(dyn_arr.at(i) == vec_int.at(i)); + } + } + + endo: + + std::cout << "Fixed list: "; + for (int i = 0; i < vec_int.size(); i++) { + std::cout << vec_int.at(i) << " "; + } + std::cout << std::endl; + + printf( + "algo_01 is %s than algo_02 by %.0f microseconds", + (fft > sft? "slower" : "faster"), fabs(fft - sft) + ); + + return 0; +} + +void algo_01(DynIntArr &cont) { + if (cont.size() <= 2) { // See this_file:97 + return; + } + + int step = (cont.at(cont.size()-1) - cont.at(0)) / (cont.size() - 1); + int miss_pos = -1; + for (int i = 1; i < cont.size(); i++) { + int p = cont.at(i - 1), + c = cont.at(i); + + if (c - p != step) { + miss_pos = i; + break; + } + } + + if (miss_pos != -1) { + int val = cont.at(0) - step; + int elc = cont.size() + 1; + cont = DynIntArr(cont.size() + 1); + for (int i = 0; i < elc; i++) { + cont.add(val += step); + } + } +} + +void algo_02(std::vector &cont) { + if (cont.size() <= 2) { // See this_file:97 + return; + } + + int step = (cont.at(cont.size()-1) - cont.at(0)) / (cont.size() - 1); + int miss_pos = -1; + for (int i = 1; i < cont.size(); i++) { + int p = cont.at(i - 1), + c = cont.at(i); + + if (c - p != step) { + miss_pos = i; + break; + } + } + + if (miss_pos != -1) { + int val = cont.at(0) - step; + int elc = cont.size() + 1; + cont.clear(); + for (int i = 0; i < elc; i++) { + cont.push_back(val += step); + } + } +} + + +// Задана арифметическая прогрессия с одним пропущенным элементом. +// Выявить пропущенное и восстановить его в положенном месте.