» » » » C++17 STL Стандартная библиотека шаблонов - Яцек Галовиц

C++17 STL Стандартная библиотека шаблонов - Яцек Галовиц

На нашем литературном портале можно бесплатно читать книгу C++17 STL Стандартная библиотека шаблонов - Яцек Галовиц, Яцек Галовиц . Жанр: Программирование. Онлайн библиотека дает возможность прочитать весь текст и даже без регистрации и СМС подтверждения на нашем литературном портале litmir.org.
C++17 STL Стандартная библиотека шаблонов - Яцек Галовиц
Название: C++17 STL Стандартная библиотека шаблонов
Дата добавления: 15 июнь 2024
Количество просмотров: 138
Читать онлайн

Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних просмотр данного контента СТРОГО ЗАПРЕЩЕН! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту readbookfedya@gmail.com для удаления материала

C++17 STL Стандартная библиотека шаблонов читать книгу онлайн

C++17 STL Стандартная библиотека шаблонов - читать бесплатно онлайн , автор Яцек Галовиц

С++ — объектно-ориентированный язык программирования, без которого сегодня немыслима промышленная разработка ПО. В этой замечательной книге описана работа с контейнерами, алгоритмами, вспомогательными классами, лямбда-выражениями и другими интересными инструментами, которыми богат современный С++. Освоив материал, вы сможете коренным образом пересмотреть привычный подход к программированию.
Преимущество издания — в подробном описании стандартной библиотеки шаблонов С++, STL. Ее свежая версия была выпущена в 2017 году. В книге вы найдете более 90 максимально реалистичных примеров, которые демонстрируют всю мощь STL. Многие из них станут базовыми кирпичиками для решения более универсальных задач.
Вооружившись этой книгой, вы сможете эффективно использовать С++17 для создания высококачественного и высокопроизводительного ПО, применимого в различных отраслях.

1 ... 57 58 59 60 61 ... 121 ВПЕРЕД
Перейти на страницу:
из диапазона 0...(w*h–1). Эти числа можно использовать в качестве входного источника для нашего диапазона данных функции преобразования, который мы инкапсулировали, применяя to_iteration_count.

  vector<int> v (w * h);

  iota(begin(v), end(v), 0);

  transform(begin(v), end(v), begin(v), to_iteration_count);

10. На этом, по сути, все. Теперь у нас есть вектор v, который мы инициализировали одномерными координатами и переписали счетчиком итераций для множества Мандельброта. На его основе можно вывести красивое изображение. Можно сделать окно консоли длиной w символов, чтобы не выводить на экран символ перевода строки. Но мы можем также нестандартно использовать алгоритм std::accumulate, чтобы он добавил разрывы строк за нас. Он применяет бинарную функцию для сокращения диапазона. Предоставим ему бинарную функцию, принимающую итератор вывода (который мы свяжем с терминалом на следующем шаге) и отдельное значение из диапазона. Выведем это значение как символ *, если количество итераций превышает 50. В противном случае выведем пробел. При нахождении в конце строки (поскольку переменная-счетчик n без остатка делится на w) выведем символ разрыва строки:

  auto binfunc ([w, n{0}] (auto output_it, int x) mutable {

    *++output_it = (x > 50 ? '*' : ' ');

    if (++n % w == 0) { ++output_it = 'n'; }

      return output_it;

  });

11. Вызывая функцию std::accumulate для входного диапазона данных вместе с нашей бинарной функцией print и итератором ostream_iterator, можно отправить рассчитанное множество Мандельброта в окно консоли:

  accumulate(begin(v), end(v), ostream_iterator<char>{cout},

             binfunc);

}

12. Компиляция и запуск программы приводят к следующему результату, который выглядит как изначальное детализированное множество Мандельброта в упрощенной форме (рис. 6.9).

Как это работает

Все расчеты происходят во время вызова std::transform для одномерного массива:

vector<int> v (w * h);

iota(begin(v), end(v), 0);

transform(begin(v), end(v), begin(v), to_iteration_count);

Что же произошло и почему это работает именно так? Функция to_iteration_count, по сути, представляет собой цепочку вызовов от i_to_xy до scale и mandelbrot_iterations. На рис. 6.10 показаны этапы преобразования.

Подобным способом в качестве входного параметра можно использовать индекс одномерного массива и получать количество итераций множества Мандельброта для точки двумерной плоскости, которую представляет точка массива. К счастью, эти три преобразования совершенно не взаимозависимы. Модули подобного кода можно легко протестировать отдельно друг от друга. Таким образом, находить и исправлять ошибки очень легко, как и просто утверждать о корректности кода. 

Создаем собственный алгоритм split

В некоторых ситуациях существующих алгоритмов STL недостаточно. Но ничто не запрещает нам реализовать собственный алгоритм. Прежде чем решать конкретную задачу, следует тщательно ее обдумать, чтобы понять: многие задачи можно решить путем обобщения. Если мы будем регулярно добавлять в наши библиотеки новый код по мере решения собственных задач, то можем помочь коллегам-программистам, у которых появятся аналогичные задачи. Идея заключается в том, чтобы знать, когда ваш код является достаточно обобщенным и когда не нужно обобщать его еще больше, в противном случае у нас получится новый язык общего назначения.

В этом примере мы реализуем алгоритм, который назовем split. Он может разбить любой диапазон данных, используя в качестве разделителя каждое включение конкретного значения, и скопировать полученный результат в выходной диапазон данных.

Как это делается

В данном примере мы реализуем собственный алгоритм split и проверим его работу, разбив на фрагменты строку-пример.

1. Сначала включим некоторые части библиотеки STL и объявим об использовании пространства имен std:

#include <iostream>

#include <string>

#include <algorithm>

#include <iterator>

#include <list>

using namespace std;

2. Алгоритм, показанный в этом разделе, предназначен для разбиения диапазонов данных. Он принимает начальный и конечный итераторы, а также итератор вывода, что поначалу делает его похожим на алгоритмы std::copy и std::transform. Другими его параметрами являются split_val и bin_func. Параметр split_val — значение, которое мы ищем во входном диапазоне данных; оно представляет собой точку разбиения, по которой мы отделяем входной диапазон данных. Параметр bin_func — функция, преобразующая пару итераторов, которые отмечают начало и конец этого поддиапазона. Мы проитерируем по входному диапазону данных с помощью std::find, так что будем перескакивать между включениями значений split_val. При разбиении отдельной строки на отдельные слова мы станем перескакивать от пробела к пробелу. При нахождении искомого значения останавливаемся, чтобы сформировать фрагмент и передать его в выходной диапазон данных:

template <typename InIt, typename OutIt, typename T, typename F>

InIt split(InIt it, InIt end_it, OutIt out_it, T split_val,

           F bin_func)

{

  while (it != end_it) {

    auto slice_end (find(it, end_it, split_val));

    *out_it++ = bin_func(it, slice_end);

    if (slice_end == end_it) { return end_it; }

    it = next(slice_end);

  }

  return it;

}

3. Воспользуемся новым алгоритмом. Создадим строку, которую затем разобьем на части. Элементом, отмечающим конец последнего фрагмента и начало следующего, будет дефис '-':

int main()

{

  const string s {"a-b-c-d-e-f-g"};

4. Когда алгоритм вызывает функцию bin_func для пары итераторов, мы хотим создать на его основе новую строку:

  auto binfunc ([](auto it_a, auto it_b) {

    return string(it_a, it_b);

  });

5. Выходной диапазон данных представляет собой список строк. Мы вызовем алгоритм split, который спроектирован так, что похож на другие алгоритмы STL:

  list<string> l;

  split(begin(s), end(s), back_inserter(l), '-', binfunc);

6. Чтобы увидеть полученное, выведем на экран новый список разбитых строк:

  copy(begin(l), end(l), ostream_iterator<string>{cout, "n"});

}

7. Компиляция и запуск программы дадут следующий результат. Он не содержит дефисов и показывает, что включает отдельные слова (которые в нашем примере являются отдельными символами):

$ ./split

a

b

c

d

e

f

g

Как это работает

Алгоритм split работает так же, как и std::transform, поскольку принимает начальный и конечный итераторы входного диапазона данных и итератор вывода. Он выполняет какие-то действия с входным диапазоном и

1 ... 57 58 59 60 61 ... 121 ВПЕРЕД
Перейти на страницу:
Комментариев (0)