init commit

This commit is contained in:
2025-04-13 21:48:15 +03:00
commit 23255e9121
192 changed files with 12200 additions and 0 deletions
+259
View File
@@ -0,0 +1,259 @@
# Третий семинар
## Шаблоны
```cpp
// template <typename>
template <class T>
void swap(T& a, T& b) {
T tmp;
tmp = a;
a = b;
b = tmp;
}
```
Можно применять и от нескольких неизвестных параметров
```cpp
template <typename T, typename K>
void transfer(T fromAccount, T toAccount, K code, int sum)
{
std::cout << "From: " << fromAccount << "\nTo: " << toAccount
<< "\nSum: " << sum << "\nCode: " << code << std::endl;
}
```
Пример кода для абсолютного значения:
```cpp
template <class T> T abs(const T& x) {
// template <class T> T abs(T x) {
return x >= 0 ? x : -x;
}
```
Суммирование элементов массива
```cpp
template <class T> T sum(T* mas, int N) {
T res = 0;
for (int i = 0; i < N; ++i) {
res += mas[i];
}
return res;
}
int main() {
double mas[5] = {...};
std::cout << sum(mas, 5);
return 0;
}
```
```cpp
template <class T> T sum(T* mas, int N) {
T res = 0;
for (int i = 0; i < N; ++i) {
res += mas[i];
}
return res;
}
int main() {
double mas[5] = {...};
std::cout << sum<double, 5>(mas);
return 0;
}
```
## Что-то про стэк
Вторая задача:
Суть была реализовывать динамически расширяемый массив
```cpp
template<class T, int SIZE>
class st {
T st[SIZE];
int top = 0;
public:
void push(T a) {
if (top == SIZE) {
// error
} else {
st[top++] = a;
}
}
T pop();
}
template<class T, int SIZE>
T st<T, SIZE>::pop() {
return st[--top];
}
```
Если указать стандартное значение для каких-то параметров, вызов обычный
## Библиотеки
### Контейнеры
#### Последовательности
- list - двунаправленный список
- vector
- deque - очередь
На их основе создаются:
- stack
- queue
#### Ассоциативные массивы
- map - отображения
- multimap - ключ может несколько раз встречаться
- set - уникальные упорядоченные ключи
- multiset - совпадающие ключи
### Итераторы
`#include <algorithm>` - подключение библиотеки
- value_type - тип значений в контейнере
- size_type - аналог size_t
- reference/ const reference - ссылки на элемент
- pointer/const pointer - указатели
Исполняют роль указателей
Для каждого контейнера определён:
- iterator - идёт от начала
- reverse_iterator - идёт с конца
- const_iterator - не меняет значений
- const_reverse_iterator - не меняет значений, ревёрс
```cpp
begin(), end();
rbegin(), rend();
cbegin(), cend(); // для константных
```
Виды итераторов:
- input
- output
- forward
- bidirectional - list, map, set
- random_access - для vector deque, можно индексировать, += n
```cpp
#include <vector>
int main() {
vector<int> v1; // длина 0
vector<int> v2(5); // длина 5, занулены
vector<int> v3(10, '*');
int m[] = {1, 2, 3, 4};
vector<int> v4(m, m + 4);
// vector<int> v4(m.begin(), m.end());
}
```
```cpp
for (int i = 0; i < v.size(); ++i)
cout << v[i] << " "; // только для random_access контейнера
v[i] == v.at(i) // выдаёт out_of_range, если нет элемента
```
Печать элементов в прямом и обратном при помощи итераторов
```cpp
#include <vector>
#include <iostream>
// прямой с помощью прямого
void f1(std::vector<int> mas) {
std::vector<int>::std::iterator iter = mas.begin();
while (iter != mas.end()) {
std::cout << *iter << " ";
iter++;
}
}
// обратный с помощью реверсивного
void f2(std::vector<int> mas) {
std::vector<int>::std::reverse_iterator iter = mas.rbegin();
while (iter != mas.rend()) {
std::cout << *iter << " ";
iter++;
}
}
// обратный с помощью прямого
void f3(std::vector<int> mas) {
std::vector<int>::std::iterator iter = mas.end();
while (iter != mas.begin()) {
--iter;
std::cout << *iter << " ";
}
}
```
Или же код нормального человека:
```cpp
for (auto x : v) cout << x << " ";
```
### Алгоритмы
Некоторые методы контейнеров:
- `size_type size()` - количество элементов в контейнере
- `bool empty()` - пустой ли контейнер
- `void clear()` - очищает контейнер
- `void push_back()` - добавляет в конец value_type<>
- `void pop_back()` - удаляет последний элемент
- `reference back()` - возвращает ссылку на последний элемент
- `reference front()` - возвращает ссылку на первый элемент
- `iterator insert(iterator p, value_type<>)` - вставка перед позицией p, возвращает на новый элемент
- `iterator erase(iterator p)` - удаляет, куда указывает, возвращает итератор на некст элемент
- `iterator erase(iterator p1, iterator p2)` - c первого до последнего (не включительно)
для list, deque
- `void push_front(value_type<>)`
- `void pop_front(value_type<>)`
Для bidirectional итераторов можно использовать
- `advance(p1, 3)` для плюса
- `n = distance(p1, p2)` для вычитания
```cpp
void f(vactor<char>& mas) {
auto iter = mas.begin();
while (iter < mas.end()) {
++iter;
if (iter != mas.end())
iter = mas.erase(iter);
}
}
```