[3sem] dsaa02 mod protecc and general fix

This commit is contained in:
unknown 2020-09-23 17:55:54 +07:00
parent 9c08f81b5d
commit a8a525df81

View file

@ -6,6 +6,7 @@
#include <chrono> #include <chrono>
#include <cmath> #include <cmath>
#include <cassert> #include <cassert>
#include <list>
#ifdef DEBUG #ifdef DEBUG
#define printf_d printf #define printf_d printf
@ -20,12 +21,10 @@ private:
int _capacity; int _capacity;
void _resize(int new_size) { void _resize(int new_size) {
int *new_container = new int [new_size]; int *new_container = new int [new_size]{0};
for (int i = 0; i < this->_size; i++) { std::copy(this->container, this->container + this->size(), new_container);
*(new_container + i) = *(this->container + i); delete [] this->container;
} this->container = new_container;
std::swap(this->container, new_container);
delete [] new_container;
this->_capacity = new_size; this->_capacity = new_size;
} }
@ -35,9 +34,7 @@ public:
this->container = new int [this->_capacity]{0}; this->container = new int [this->_capacity]{0};
} }
~DynIntArr() { ~DynIntArr() {
if (this->container != nullptr) { delete [] this->container;
delete [] this->container;
}
} }
int &at(int pos) { int &at(int pos) {
@ -54,6 +51,20 @@ public:
this->at(this->_size++) = val; this->at(this->_size++) = val;
} }
void insert(int pos, int val) {
if (pos < 0 || pos > this->_capacity) {
throw std::runtime_error("Illegal array access");
}
if (this->_size+1 > this->_capacity) {
this->_resize(this->_capacity*2);
}
for (int i = this->size(); i > pos; i--) {
this->at(i) = this->at(i-1);
}
this->at(pos) = val;
this->_size += 1;
}
int size() const { // NOLINT(modernize-use-nodiscard) int size() const { // NOLINT(modernize-use-nodiscard)
return this->_size; return this->_size;
} }
@ -72,27 +83,31 @@ inline void time_passed(std::chrono::system_clock::time_point start, double &hol
void algo_01(DynIntArr &cont); // algo with my container void algo_01(DynIntArr &cont); // algo with my container
void algo_02(std::vector<int> &cont); // algo with stl's vector void algo_02(std::vector<int> &cont); // algo with stl's vector
void algo_03(std::list<int> &cont); // algo with stl's list
// let's assume we are not including reading of data into algo's time // let's assume we are not including reading of data into algo's time
// 'cause it can at worst be O(inf) // 'cause it can at worst be O(inf)
int main() { int main() {
int reserve = 50; int reserve = 50;
DynIntArr dyn_arr(reserve); std::list<int> lst_int;
std::vector<int> vec_int; std::vector<int> vec_int;
vec_int.reserve(reserve); vec_int.reserve(reserve);
DynIntArr dyn_arr(reserve);
int N = 0; int N = 0;
std::cout << "N="; std::cout << "N=";
std::cin >> N; std::cin >> N;
auto lit = lst_int.begin();
for (int i = 0; i < N; i++) { for (int i = 0; i < N; i++) {
int num = 0; int num = 0;
std::cin >> num; std::cin >> num;
dyn_arr.add(num); dyn_arr.add(num);
vec_int.push_back(num); vec_int.push_back(num);
lst_int.push_back(num);
} }
double fft, sft = fft = 0; double fft, sft, tft = sft = fft = 0;
if (N <= 2) { // Well, even if smth. is missed there is no way to determine if (N <= 2) { // Well, even if smth. is missed there is no way to determine
goto endo; goto endo;
@ -108,10 +123,18 @@ int main() {
algo_02(vec_int); algo_02(vec_int);
time_passed(start, sft); time_passed(start, sft);
} }
{ // algo with stl's list
auto start = std::chrono::high_resolution_clock::now();
algo_03(lst_int);
time_passed(start, tft);
}
{ // let's check integrity of content { // let's check integrity of content
assert(dyn_arr.size() == vec_int.size()); assert(dyn_arr.size() == vec_int.size());
assert(dyn_arr.size() == lst_int.size());
auto lit = lst_int.begin();
for (int i = 0; i < dyn_arr.size(); i++) { for (int i = 0; i < dyn_arr.size(); i++) {
assert(dyn_arr.at(i) == vec_int.at(i)); assert(dyn_arr.at(i) == vec_int.at(i));
assert(dyn_arr.at(i) == *(lit++));
} }
} }
@ -124,19 +147,24 @@ int main() {
std::cout << std::endl; std::cout << std::endl;
printf( printf(
"algo_01 is %s than algo_02 by %.0f microseconds", "algo_01 is %s than algo_02 by %.0f microseconds\n",
(fft > sft? "slower" : "faster"), fabs(fft - sft) (fft > sft? "slower" : "faster"), fabs(fft - sft)
); );
printf(
"algo_01 is %s than algo_03 by %.0f microseconds\n",
(fft > tft? "slower" : "faster"), fabs(fft - tft)
);
return 0; return 0;
} }
void algo_01(DynIntArr &cont) { void algo_01(DynIntArr &cont) {
if (cont.size() <= 2) { // See this_file:97 if (cont.size() <= 2) { // See this_file:112
return; return;
} }
int step = (cont.at(cont.size()-1) - cont.at(0)) / (cont.size() - 1); int step = (cont.at(cont.size()-1) - cont.at(0)) / (cont.size());
int miss_pos = -1; int miss_pos = -1;
for (int i = 1; i < cont.size(); i++) { for (int i = 1; i < cont.size(); i++) {
int p = cont.at(i - 1), int p = cont.at(i - 1),
@ -149,21 +177,17 @@ void algo_01(DynIntArr &cont) {
} }
if (miss_pos != -1) { if (miss_pos != -1) {
int val = cont.at(0) - step; int val = cont.at(miss_pos) - step;
int elc = cont.size() + 1; cont.insert(miss_pos, val);
cont = DynIntArr(cont.size() + 1);
for (int i = 0; i < elc; i++) {
cont.add(val += step);
}
} }
} }
void algo_02(std::vector<int> &cont) { void algo_02(std::vector<int> &cont) {
if (cont.size() <= 2) { // See this_file:97 if (cont.size() <= 2) { // See this_file:112
return; return;
} }
int step = (cont.at(cont.size()-1) - cont.at(0)) / (cont.size() - 1); int step = (cont.at(cont.size()-1) - cont.at(0)) / (cont.size());
int miss_pos = -1; int miss_pos = -1;
for (int i = 1; i < cont.size(); i++) { for (int i = 1; i < cont.size(); i++) {
int p = cont.at(i - 1), int p = cont.at(i - 1),
@ -176,13 +200,37 @@ void algo_02(std::vector<int> &cont) {
} }
if (miss_pos != -1) { if (miss_pos != -1) {
int val = cont.at(0) - step; auto vit = cont.begin();
int elc = cont.size() + 1; std::advance(vit, miss_pos);
cont.clear(); cont.insert(vit, *vit - step);
for (int i = 0; i < elc; i++) { }
cont.push_back(val += step); }
void algo_03(std::list<int> &cont) {
if (cont.size() <= 2) { // See this_file:112
return;
}
int step = (cont.back() - cont.front()) / (cont.size());
int miss_pos = -1;
{
auto lit = cont.begin();
for (int i = 1; i < cont.size(); i++) {
int p = *lit++,
c = *(lit);
if (c - p != step) {
miss_pos = i;
break;
}
} }
} }
if (miss_pos != -1) {
auto lit = cont.begin();
std::advance(lit, miss_pos);
cont.insert(lit, *lit - step);
}
} }