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
cmc/seminars/3.md
T
2025-04-13 21:48:15 +03:00

6.0 KiB
Raw Blame History

Третий семинар

Шаблоны

// template <typename>
template <class T>
void swap(T& a, T& b) {
    T tmp;
    tmp = a;
    a = b;
    b = tmp;
}

Можно применять и от нескольких неизвестных параметров

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

Пример кода для абсолютного значения:

template <class T> T abs(const T& x) {
// template <class T> T abs(T x) {
    return x >= 0 ? x : -x;
}

Суммирование элементов массива

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

Что-то про стэк

Вторая задача: Суть была реализовывать динамически расширяемый массив

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 - не меняет значений, ревёрс
begin(), end();
rbegin(), rend();

cbegin(), cend(); // для константных

Виды итераторов:

  • input
  • output
  • forward
  • bidirectional - list, map, set
  • random_access - для vector deque, можно индексировать, += n
#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()); 
}
for (int i = 0; i < v.size(); ++i)
  cout << v[i] << " "; // только для random_access контейнера

v[i] == v.at(i) // выдаёт out_of_range, если нет элемента

Печать элементов в прямом и обратном при помощи итераторов

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

Или же код нормального человека:

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) для вычитания
void f(vactor<char>& mas) {
  auto iter = mas.begin();

  while (iter < mas.end()) {
    ++iter;
    
    if (iter != mas.end())
      iter = mas.erase(iter);
  }
}