init commit
This commit is contained in:
+180
@@ -0,0 +1,180 @@
|
||||
# Шаблонные функции с контейнером на вход
|
||||
|
||||
-> написать шаблонную функцию, которая ищет макс значение в константном или неконстантном контейнере
|
||||
|
||||
```cpp
|
||||
#include <iostream>
|
||||
#include <list>
|
||||
#include <vector>
|
||||
|
||||
using namespace std;
|
||||
|
||||
template <typename T>
|
||||
typename T::value_type Max(const T& c) {
|
||||
// используем константные итераторы cbegin
|
||||
typename T::value_type max = *c.cbegin();
|
||||
|
||||
for (const auto& it : c) {
|
||||
if (*it > max) {
|
||||
max = *it;
|
||||
}
|
||||
max = *it > max ? *it : max
|
||||
}
|
||||
|
||||
return max;
|
||||
}
|
||||
|
||||
|
||||
int main() {
|
||||
list<int> l = { 1, 2, 3, 4, 5 };
|
||||
cout << Max<list<int>>(l) << endl;
|
||||
|
||||
vector<long> v = { 1, 2, 3, 4, 5 };
|
||||
cout << Max<vector<long>>(v) << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
Шаблонная функция, которая удваивает все элементы в контейнере
|
||||
Из [1, 2, 3] делает [1, 1, 2, 2, 3, 3]
|
||||
|
||||
```cpp
|
||||
// работает, но херня, много памяти жрёт
|
||||
template <typename T>
|
||||
void dbl(T& c) {
|
||||
T res;
|
||||
auto it = c.begin();
|
||||
while (it != c.end()) {
|
||||
res.push_back(*it);
|
||||
res.push_back(*it);
|
||||
++it;
|
||||
}
|
||||
|
||||
c = res;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// работает, всё правильно
|
||||
template <typename T>
|
||||
void dbl(T& c) {
|
||||
auto it = c.begin();
|
||||
// typename T::iterator it = c.begin(); - порой могут вот так просить на коллоквиуме
|
||||
|
||||
while (it != c.end()) {
|
||||
it = c.insert(++it, *it);
|
||||
++it;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
вход функции: 2 итератора, реверсирующая данную коллекцию
|
||||
Было [1, 2, 3] Стало [3, 2, 1]
|
||||
|
||||
```cpp
|
||||
template <typename T>
|
||||
void rever(T b, T e) {
|
||||
if (b == e) return; // для проверки на пустой контейнер
|
||||
|
||||
--e;
|
||||
|
||||
while (b != e) { // просто сравнивать нельзя у листов
|
||||
swap(*b++, *e); // нативный свап
|
||||
|
||||
if (b == e) break;
|
||||
|
||||
--e;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
```
|
||||
|
||||
функции подаётся 2 итератора, предикат и стандартное значение
|
||||
Предикат - объект с перегруженными круглыми скобками
|
||||
|
||||
```cpp
|
||||
template<typename T, typename P> // T - указатель P - предикат
|
||||
void f(T b, T, e, P pred, typename T::value_type val) {
|
||||
|
||||
}
|
||||
|
||||
// пример предиката
|
||||
struct Pred {
|
||||
bool operation()(int v) {
|
||||
return v % 3;
|
||||
}
|
||||
}
|
||||
|
||||
int main () {
|
||||
vector<int> v = {...};
|
||||
|
||||
f(v.begin(), v.end(), Pred(), 9);
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
## Лямба-функции
|
||||
|
||||
Неименованные функции, которые можно просто вставить в выражение
|
||||
|
||||
```cpp
|
||||
int x = 5;
|
||||
auto ef = [x]() { cout << x; } // тут не обойтись без auto
|
||||
ef();
|
||||
auto ef = [](int a) { cout << a; }
|
||||
ef(x);
|
||||
```
|
||||
|
||||
В квадратных скобках - привязка к внешним элементам
|
||||
|
||||
- [] привязки нет
|
||||
- [=] привязываются все внешние
|
||||
- [&] по ссылке привязываются все внешние
|
||||
|
||||
В круглых - к тем, что передаются
|
||||
|
||||
## Алгоритм remove_if
|
||||
|
||||
```cpp
|
||||
vector <int> v = {2, 4, 5, 7, 9, 10};
|
||||
auto end = remove_if(v.begin(), v.end(), [](int x) { return x % 2 == 0; })
|
||||
```
|
||||
|
||||
remove_if перемещает в хвост все значения, для которых предикат (лямбда-функция) верна. Возвращает указатель на начало хвоста
|
||||
Вывод: [5, 7, 9, 2, 4, 10]. end указывать будет на '2'
|
||||
|
||||
## 2 задание 3го контеста
|
||||
|
||||
> есть уже complex, complex stack. Добавление в стек через операцию <<
|
||||
|
||||
посчитать польско-инвер запись для комплексных чисел. Если попадается z - значение по умолчанию
|
||||
|
||||
> map - словарик. Содержит элементы 'ключ' - 'значение'
|
||||
|
||||
```cpp
|
||||
complex eval(const vector<string>& args, const complex& z) {
|
||||
complex stack st;
|
||||
map<string, function<void()>> mp; {
|
||||
{"z", [&st, &z]() { st = st << z; }}, // если попалось z, добавили в стек
|
||||
{";", [&st]() { st = ~st; }},
|
||||
... // все прочие +/-/... операции
|
||||
}
|
||||
|
||||
for (const auto& iter : args) {
|
||||
if (s[0] != '(') { // если строка не (re,im)
|
||||
mp[s](); // просто вызвали нужное
|
||||
} else {
|
||||
st = st << complex(s);
|
||||
}
|
||||
}
|
||||
|
||||
// ответ на верхушке стека
|
||||
return +st;
|
||||
}
|
||||
```
|
||||
Reference in New Issue
Block a user