- Фантастика и фэнтези
- Ироническое фэнтези
- Стимпанк
- Детективная фантастика
- Киберпанк
- Попаданцы
- LitRPG
- Космоопера
- Технофэнтези
- Городская фантастика
- Русское фэнтези
- Юмористическая фантастика
- Космическая фантастика
- Боевое фэнтези
- Эпическая фантастика
- Зарубежная фантастика
- Книги магов
- Мистика
- Разная фантастика
- Разное фэнтези
- Любовное фэнтези
- Романтическая фантастика
- Городское фентези
- Историческая фантастика
- Историческое фэнтези
- Социально-философская фантастика
- Сказочная фантастика
- Иностранное фэнтези
- Романтическое фэнтези
- Ироническая фантастика
- Ужасы и Мистика
- Постапокалипсис
- Героическая фантастика
- Фэнтези
- Научная Фантастика
- Социально-психологическая
- Альтернативная история
- Боевая фантастика
- Разная литература
- Пословицы, поговорки
- Шахматы
- Визуальные искусства
- Фанфик
- Авто и ПДД
- Военное
- Отраслевые издания
- Гиды, путеводители
- Зарубежная образовательная литература
- Военная история
- Цитаты из афоризмов
- Современная литература
- Великолепные истории
- Начинающие авторы
- Современная зарубежная литература
- Боевые искусства
- Изобразительное искусство, фотография
- Кино
- Литература 19 века
- Недвижимость
- Музыка, музыканты
- Готические новеллы
- Истории из жизни
- Культура и искусство
- Спецслужбы
- Зарубежная прикладная литература
- Музыка, танцы
- Подростковая литература
- Прочее
- Военная техника, оружие
- Газеты и журналы
- Периодические издания
- Домоводство, Дом и семья
- Любовные романы
- Экономическая литература
- Научные и научно-популярные книги
- О животных
- Биохимия
- Культурология
- Юриспруденция
- Политика
- Психотерапия
- Языкознание
- Научпоп
- Медицина
- Психология, личное
- Радиотехника
- Филология
- Педагогика
- Образовательная литература
- Деловая литература
- Физика
- Науки: разное
- Химия
- Воспитание детей, педагогика
- Детская психология
- Зарубежная публицистика
- Биология
- Архитектура
- Зарубежная психология
- Науки о космосе
- Социология
- Математика
- География
- Беременность, ожидание детей
- Литературоведение
- Транспорт, военная техника
- Обществознание
- Зоология
- География
- Альтернативная медицина
- Иностранные языки
- Ветеринария
- Рефераты
- Астрология
- Биофизика
- Экология
- История Европы
- Учебники
- Шпаргалки
- Государство и право
- Ботаника
- Религиоведение
- История
- Техническая литература
- Прочая научная литература
- Психология
- Детективы и Триллеры
- Справочная литература
- Проза
- Новелла
- Юмор
- Проза
- Историческая проза
- Русская современная проза
- Советская классическая проза
- Повести
- Очерки
- Эссе
- Рассказы
- Зарубежная современная проза
- Сентиментальная проза
- Зарубежная классика
- Афоризмы
- Эпистолярная проза
- Феерия
- Семейный роман/Семейная сага
- Разное
- Антисоветская литература
- Магический реализм
- Русская классическая проза
- Современная проза
- О войне
- Контркультура
- Классическая проза
- Поэзия, Драматургия
- Детская литература
- Детская фантастика
- Детские остросюжетные
- Детские стихи
- Детские приключения
- Внеклассное чтение
- Учебная литература
- Зарубежные детские книги
- Бизнес
- Загадки
- Книги для подростков
- Школьные учебники
- Детский фольклор
- Книги для дошкольников
- Детские детективы
- Детская познавательная и развивающая литература
- Буквари
- Прочая детская литература
- Сказка
- Детская проза
- Детская образовательная литература
- Юмор
- Документальные книги
- Бизнес
- Внешнеэкономическая деятельность
- Тайм-менеджмент
- Кадровый менеджмент
- О бизнесе популярно
- Управление, подбор персонала
- Бизнес
- Менеджмент и кадры
- Продажи
- Экономика
- Ценные бумаги и инвестиции
- Малый бизнес
- Делопроизводство, офис
- Корпоративная культура, бизнес
- Банковское дело
- Финансы
- Зарубежная деловая литература
- Ораторское искусство / риторика
- Личные финансы
- Интернет-бизнес
- Поиск работы
- Государственное и муниципальное управление
- Бухучет и аудит
- Работа с клиентами
- Менеджмент
- Краткое содержание
- Личная эффективность
- Переговоры
- Приключения
- Старинная литература
- Религия и духовность
- Компьютеры и Интернет
- Блог
Читаем без скачивания C++17 STL Стандартная библиотека шаблонов - Яцек Галовиц
Шрифт:
Интервал:
Закладка:
Функция std::sample не добавляет случайные значения к пробным точкам с фиксированным шагом, она выбирает полностью случайные точки; поэтому в рамках данного примера работает несколько по-другому.
Как это делается
В этом примере мы создадим выборку для очень большого вектора, содержащую случайные данные. Они имеют нормальное распределение. После завершения выборки полученные результаты все еще будут показывать нормальное распределение, что мы и проверим.
1. Сначала включим все заголовочные файлы, которые будем применять, а также объявим об использовании пространства имен std, чтобы сэкономить немного времени на вводе текста:
#include <iostream>
#include <vector>
#include <random>
#include <algorithm>
#include <iterator>
#include <map>
#include <iomanip>
using namespace std;
2. С кодом работать будет гораздо проще, если мы сконфигурируем конкретные характеристики нашего алгоритма с помощью константных переменных. Укажем размер большого вектора случайных чисел, а также количество точек:
int main()
{
const size_t data_points {100000};
const size_t sample_points {100};
3. Большой вектор, заполненный случайными числами, должен наполняться с помощью генератора случайных чисел, выдающего числа, которые будут иметь нормальное распределение. Любое нормальное распределение характеризуется математическим ожиданием и квадратическим отклонением:
const int mean {10};
const size_t dev {3};
4. Теперь настроим генератор случайных чисел. Сначала создадим экземпляр random_device и вызовем его один раз, чтобы получить исходное значение для конструктора генератора случайных чисел. Далее создадим объект распределения, который применяет нормальное распределение к полученным случайным числам:
random_device rd;
mt19937 gen {rd()};
normal_distribution<> d {mean, dev};
5. Создадим экземпляр вектора, содержащего целые числа, и заполним его случайными числами. Это можно сделать с помощью алгоритма std::generate_n, который вызовет объект функции генератора, чтобы передать его возвращаемое значение в наш вектор благодаря итератору back_inserter. Объект функции генератора оборачивает выражение d(gen), получающее случайное число от случайного устройства и передает его в объект распределения:
vector<int> v;
v.reserve(data_points);
generate_n(back_inserter(v), data_points,
[&] { return d(gen); });
6. Теперь создадим еще один вектор, который содержит гораздо меньший диапазон точек:
vector<int> samples;
v.reserve(sample_points);
7. Алгоритм std::sample работает аналогично алгоритму std::copy, но при этом принимает два дополнительных параметра — количество точек, получаемых из входного диапазона данных, и объект генератора случайных чисел, к которому он будет обращаться, чтобы получить случайные позиции пробных точек:
sample(begin(v), end(v), back_inserter(samples),
sample_points, mt19937{random_device{}()});
8. С выборкой мы закончили. Остальная часть кода посвящена отображению данных. Входные данные имеют нормальное распределение, и если алгоритм выборки отработал хорошо, то полученный вектор тоже должен иметь такое же распределение. Чтобы увидеть, насколько распределение отклоняется от нормального, выведем на экран гистограмму значений:
map<int, size_t> hist;
for (int i : samples) { ++hist[i]; }
9. Наконец, пройдем в цикле по всем элементам, чтобы вывести нашу гистограмму на экран:
for (const auto &[value, count] : hist) {
cout << setw(2) << value << " "
<< string(count, '*') << 'n';
}
}
10. После компиляции и запуска программы мы видим, что полученный вектор имеет характеристики нормального распределения (рис. 5.5):
Как это работает
Алгоритм std::sample — это новый алгоритм, который появился в версии С++17. Его сигнатура выглядит следующим образом:
template<class InIterator, class OutIterator,
class Distance, class UniformRandomBitGenerator>
OutIterator sample(InIterator first, InIterator last,
SampleIterator out, Distance n,
UniformRandomBitGenerator&& g);
Входной диапазон данных обозначается итераторами first и last, в то время как out — итератор вывода. Эти итераторы выполняют ту же функцию, что и для функции std::copy; элементы копируются из одного диапазона в другой. Алгоритм std::sample является особенным с той точки зрения, что копирует только часть входного диапазона, поскольку делает выборку только n элементов. Он использует равномерное распределение внутри системы, поэтому каждая точка на графике во входном диапазоне данных может быть выбрана с одинаковой вероятностью.
Выполняем перестановки во входных последовательностях
При тестировании кода, который должен работать с последовательностями входных данных, где порядок аргументов не так важен, полезно проверять, получаем ли мы одинаковый результат во всех возможных перестановках для этих входных данных. Такой тест может, например, проверять, корректно ли работает ваш собственный алгоритм сортировки.
Независимо от того, зачем нужны все перестановки для какого-то диапазона значений, std::next_permutation позволит это реализовать. Можно вызвать эту функцию для изменяемого диапазона, и она изменит порядок его элементов на следующую лексикографическую перестановку.
Как это делается
В данном примере мы напишем программу, которая считывает несколько строк, содержащих слова, из стандартного потока ввода, а затем применим функцию std::next_permutation, чтобы сгенерировать и вывести на экран все перестановки для этих строк.
1. Как и обычно, сначала включим все необходимые заголовочные файлы и объявим об использовании пространства имен std:
#include <iostream>
#include <vector>
#include <string>
#include <iterator>
#include <algorithm>
using namespace std;
2. Мы начнем с вектора строк, который заполним из стандартного потока ввода. Затем отсортируем вектор:
int main()
{
vector<string> v {istream_iterator<string>{cin}, {}};
sort(begin(v), end(v));
3. Далее выведем содержимое вектора на консоль. Затем вызовем функцию std::next_permutation. Она систематически перемешивает содержимое вектора, чтобы сгенерировать перестановки этих элементов, которое мы снова выведем на экран. Вызов next_permutation вернет значение false, когда будет сгенерирована последняя перестановка.
do {
copy(begin(v), end(v),
ostream_iterator<string>{cout, ", "});
cout << 'n';
} while (next_permutation(begin(v), end(v)));
}
4. Скомпилируем и запустим функцию, передав ей какие-нибудь данные:
$ echo "a b c" | ./input_permutations
a, b, c,