-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTask2.h
242 lines (202 loc) · 10.8 KB
/
Task2.h
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
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
#pragma once
#include <iostream>
#include <fstream>
#include <stdexcept>
using namespace std;
template <typename T>
class List {
private:
// Вложенная структура для узлов списка
struct Node {
T data; // Хранит значение узла.
Node* next; // Указатель на следующий узел.
Node(T val) : data(val), next(nullptr) {} // Конструктор инициализирует значение узла и устанавливает указатель на nullptr.
};
Node* head; // Указатель на первый узел списка.
int size; // Хранит количество элементов в списке.
// Дружественный шаблонный класс MySet, чтобы дать ему доступ к приватным членам List.
template <typename U>
friend class MySet;
public:
List() : head(nullptr), size(0) {} // Конструктор инициализирует пустой список.
// Добавление элемента в конец списка
void add(T element) {
Node* newNode = new Node(element); // Создаем новый узел.
if (!head) { // Если список пуст:
head = newNode; // Новый узел становится головой списка.
} else { // Если список не пуст:
Node* current = head; // Начинаем с головы списка.
while (current->next) { // Проходим до последнего узла.
current = current->next;
}
current->next = newNode; // Присоединяем новый узел в конец списка.
}
size++; // Увеличиваем размер списка.
}
// Удаление элемента из списка
void remove(T element) {
if (!head) return; // Если список пуст, ничего не делаем.
if (head->data == element) { // Если элемент находится в голове списка:
Node* temp = head; // Временный указатель на голову.
head = head->next; // Перемещаем голову на следующий узел.
delete temp; // Удаляем старую голову.
size--; // Уменьшаем размер списка.
return;
}
Node* current = head; // Указатель на текущий узел.
while (current->next && current->next->data != element) {
current = current->next; // Проходим по списку, пока не найдем элемент или не дойдем до конца.
}
if (current->next) { // Если элемент найден:
Node* temp = current->next; // Временный указатель на найденный узел.
current->next = current->next->next; // Убираем узел из цепочки.
delete temp; // Удаляем узел.
size--; // Уменьшаем размер списка.
}
}
// Проверка наличия элемента в списке
bool contains(T element) const {
Node* current = head; // Начинаем с головы списка.
while (current) { // Перебираем узлы, пока не дойдем до конца списка.
if (current->data == element) { // Если нашли элемент:
return true;
}
current = current->next; // Переходим к следующему узлу.
}
return false; // Если элемент не найден, возвращаем false.
}
// Получение размера списка
int getSize() const {
return size; // Возвращаем количество элементов в списке.
}
// Очистка списка
void clear() {
while (head) { // Пока список не пуст:
Node* temp = head; // Временный указатель на текущий узел.
head = head->next; // Перемещаем голову на следующий узел.
delete temp; // Удаляем текущий узел.
}
size = 0; // Сбрасываем размер списка.
}
// Печать списка (для отладки)
void print() const {
Node* current = head; // Начинаем с головы списка.
while (current) { // Перебираем узлы списка.
cout << current->data << " "; // Выводим значение узла.
current = current->next; // Переходим к следующему узлу.
}
cout << endl; // Завершаем вывод.
}
// Получение элемента по индексу
T get(int index) const {
if (index < 0 || index >= size) { // Проверяем, находится ли индекс в допустимом диапазоне.
throw out_of_range("Индекс вне диапазона"); // Если нет, выбрасываем исключение.
}
Node* current = head; // Начинаем с головы списка.
for (int i = 0; i < index; i++) { // Переходим к нужному узлу.
current = current->next;
}
return current->data; // Возвращаем значение узла.
}
Node* getHead() const {
return head; // Возвращаем указатель на голову списка.
}
// Функция поиска элемента на заданной позиции
bool find(int index, T value) const {
if (index < 0 || index >= size) { // Проверяем, находится ли индекс в допустимом диапазоне.
return false; // Если нет, возвращаем false.
}
Node* current = head; // Начинаем с головы списка.
int currentIndex = 0;
while (current) { // Перебираем узлы списка.
if (currentIndex == index) { // Если индекс совпадает:
return current->data == value; // Проверяем, совпадает ли значение.
}
current = current->next; // Переходим к следующему узлу.
currentIndex++;
}
return false; // Если элемент не найден, возвращаем false.
}
// Деструктор для очистки памяти
~List() {
clear(); // Очищаем список, чтобы освободить память.
}
};
template <typename T>
class MySet {
private:
List<T> list; // Используем List для хранения уникальных элементов.
public:
// Добавление элемента
void SETADD(T element) {
if (!list.contains(element)) { // Добавляем только если элемент отсутствует.
list.add(element);
}
}
// Удаление элемента
void SETDEL(T element) {
if (list.contains(element)) { // Удаляем только если элемент существует.
list.remove(element);
} else {
cout << "Элемент " << element << " не найден в множестве." << endl;
}
}
// Проверка наличия элемента
bool SET_AT(T element) const {
return list.contains(element); // Проверяем, содержится ли элемент в множестве.
}
// Получение элемента по индексу
T SETGET(int index) const {
return list.get(index); // Получаем элемент списка по индексу.
}
// Оператор сравнения
bool operator==(const MySet<T>& other) const {
if (list.getSize() != other.list.getSize()) { // Если размеры множеств различны, они не равны.
return false;
}
for (int i = 0; i < list.getSize(); ++i) { // Проверяем, содержатся ли все элементы одного множества в другом.
if (!other.SET_AT(list.get(i))) {
return false;
}
}
return true; // Множества равны, если все элементы совпадают.
}
// Загрузка множества из файла
void loadFromFile(const string& filename) {
ifstream infile(filename); // Открываем файл для чтения.
if (!infile.is_open()) {
throw runtime_error("Не удалось открыть файл для чтения");
}
T element;
while (infile >> element) { // Читаем элементы из файла.
SETADD(element); // Добавляем каждый элемент в множество.
}
infile.close(); // Закрываем файл.
}
// Выгрузка множества в файл
void saveToFile(const string& filename) const {
ofstream outfile(filename); // Открываем файл для записи.
if (!outfile.is_open()) {
throw runtime_error("Не удалось открыть файл для записи");
}
typename List<T>::Node* current = list.head; // Начинаем с головы списка.
while (current) { // Перебираем узлы списка.
outfile << current->data << endl; // Записываем значение узла в файл.
current = current->next; // Переходим к следующему узлу.
}
outfile.close(); // Закрываем файл.
}
// Печать множества
void print() const {
cout << "Множество: ";
list.print(); // Выводим элементы списка.
}
// Получение размера множества
int getSize() const {
return list.getSize(); // Возвращаем количество элементов множества.
}
// Очистка множества
void clear() {
list.clear(); // Очищаем список.
}
};