This repository has been archived on 2026-07-28. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
2025-04-13 21:48:15 +03:00

4.8 KiB

Шаблонные функции с контейнером на вход

-> написать шаблонную функцию, которая ищет макс значение в константном или неконстантном контейнере

#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]

// работает, но херня, много памяти жрёт
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]

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 итератора, предикат и стандартное значение Предикат - объект с перегруженными круглыми скобками

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;
}

Лямба-функции

Неименованные функции, которые можно просто вставить в выражение

int x = 5;
auto ef = [x]() { cout << x; } // тут не обойтись без auto
ef();
auto ef = [](int a) { cout << a; }
ef(x);

В квадратных скобках - привязка к внешним элементам

  • [] привязки нет
  • [=] привязываются все внешние
  • [&] по ссылке привязываются все внешние

В круглых - к тем, что передаются

Алгоритм remove_if

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 - словарик. Содержит элементы 'ключ' - 'значение'

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;
}