-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlab4.cpp
174 lines (146 loc) · 5.07 KB
/
lab4.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <cmath>
#include <assert.h>
#include <cassert>
#include <stdlib.h>
#include <Windows.h>
#include <string>
#define groupno 3
using namespace std;
//epsilon for float comparison
#define EPS 0.00001
/*
Лабораторна робота 4
виконав Вітязь Денис
Варіант 3
*/
/*допоміжні функції*/
double text2nums(std::string input,int index){ //перетворення тексту в числа
//може бути розділена або пробілами або комами
bool mode = input.find(",") != std::string::npos;
char mchr = mode ? ',' : ' ';
//mode 0 - space separated
//mode 1 - comma separated
size_t pos = 0;
size_t prevpos = 0;
size_t i = 0;
std::string number;
while (pos<input.length()){
//входження розділювача
pos = input.find_first_of(mchr, prevpos);
if(pos == std::string::npos){
//як нема розділювача то це кінець
pos = input.length();
}
//вирізаємо число
number = input.substr(prevpos, pos-prevpos);
// stod - строка в double
if(i == index){
return std::stod(number);
}
prevpos = pos+1;
i++;
}
return 0;
}
size_t countcomma(std::string input){ //кількість чисел в рядку
bool mode = input.find(",") != std::string::npos;
char mchr = mode ? ',' : ' ';//можемо розділювати або пробілами або комами
return std::count(input.begin(), input.end(), mchr) + 1;
}
bool sorter(double a, double b){ //умова сортування
return fabs(a) > fabs(b);
}
void printarr(double *arr, size_t size){ //вивід масиву
std::cout<<"[";
for(size_t i = 0; i < size; i++){
std::cout << arr[i] << (i+1<size?", ":"");
}
std::cout << "]" << std::endl;
}
/*задачі*/
double* task1(std::string str,size_t* arrlen, double a, double b){
//double* - вказівник на масив, *sum - звернення до масиву
size_t totlen = countcomma(str);//кількість чисел в рядку
//вибрати пробіжок між a b, зразу порахуємо кількість елементів
*arrlen = 0;
for(int i=0; i<totlen; i++){
double num = text2nums(str,i);
if(num>=a && num<=b)
(*arrlen)++;
}
//тепер створимо масив
double* arr = new double[*arrlen];
//і заповнимо його
size_t pos = 0;
for(int i=0; i<totlen; i++){
double num = text2nums(str,i);
if(num>=a && num<=b){
arr[pos] = num;
pos++;
}
}
std::cout << "Не відсортований масив: ";
printarr(arr,*arrlen);
//сортування
std::sort(arr, arr+(*arrlen), sorter);
return arr;
}
bool test(){
//test task1
double seq[] = {1,2,3,4,5,6,7,-7,-6,-5,-4,-3,-2,-1};
double res[] = {5,4,3,-2,2,-1,1};
random_shuffle(&seq[0], &seq[14]);//перемішуємо масив
std::string in = "";
for(int i=0; i<14; i++)
in += std::to_string(seq[i]) + ((i+1<14)?", ":"");
std::cout << "Вхідний рядок: " << in << std::endl;
size_t arrlen;
double* arr = task1(in, &arrlen, -2, 5);
std::cout << "Вихідний масив: ";
printarr(arr, arrlen);
//перевірка
if(arrlen != 7){
std::cerr << "Невірна кількість елементів" << std::endl;
delete[] arr;
assert(false);
}
for(int i=0; i<7; i++){
//різниця між модулями має бути меншою за EPS (порівняння чисел з плаваючою точкою)
if(fabs( fabs(arr[i]) - fabs(res[i]) ) > EPS){
std::cerr << "Невірний елемент " << i << std::endl;
std::cout << "Очікувано: " << res[i] << std::endl;
std::cout << "Отримано: " << arr[i] << std::endl;
delete[] arr;
assert(false);
}
}
std::cout<<"Тести пройдено успішно!"<<std::endl;
delete[] arr;
return true;
}
/*основна функція*/
int main(){
//set console encoding to utf-8
SetConsoleOutputCP(CP_UTF8);
double a,b;
std::string buf;
double* arr;
size_t arrlen;
std::cout<<"Введіть послідовність розділену комами або пробілами: \n";
std::getline(std::cin, buf);
std::cout<<"Введіть a: ";
std::cin>>a;
std::cout<<"Введіть b: ";
std::cin>>b;
std::cout<<std::endl;
arr = task1(buf, &arrlen, a, b);
std::cout<<"Результат: "<<std::endl;
printarr(arr, arrlen);
std::cout<<std::endl<<"Запускаємо тести"<<std::endl;
test();
delete[] arr;//вивільнення пам'яті
return 0;
}