- Любовные романы
- Фантастика и фэнтези
- Ненаучная фантастика
- Ироническое фэнтези
- Научная Фантастика
- Фэнтези
- Ужасы и Мистика
- Боевая фантастика
- Альтернативная история
- Космическая фантастика
- Попаданцы
- Юмористическая фантастика
- Героическая фантастика
- Детективная фантастика
- Социально-психологическая
- Боевое фэнтези
- Русское фэнтези
- Киберпанк
- Романтическая фантастика
- Городская фантастика
- Технофэнтези
- Мистика
- Разная фантастика
- Иностранное фэнтези
- Историческое фэнтези
- LitRPG
- Эпическая фантастика
- Зарубежная фантастика
- Городское фентези
- Космоопера
- Разное фэнтези
- Книги магов
- Любовное фэнтези
- Постапокалипсис
- Бизнес
- Историческая фантастика
- Социально-философская фантастика
- Сказочная фантастика
- Стимпанк
- Романтическое фэнтези
- Ироническая фантастика
- Детективы и Триллеры
- Проза
- Юмор
- Феерия
- Новелла
- Русская классическая проза
- Современная проза
- Повести
- Контркультура
- Русская современная проза
- Историческая проза
- Проза
- Классическая проза
- Советская классическая проза
- О войне
- Зарубежная современная проза
- Рассказы
- Зарубежная классика
- Очерки
- Антисоветская литература
- Магический реализм
- Разное
- Сентиментальная проза
- Афоризмы
- Эссе
- Эпистолярная проза
- Семейный роман/Семейная сага
- Поэзия, Драматургия
- Приключения
- Детская литература
- Загадки
- Книга-игра
- Детская проза
- Детские приключения
- Сказка
- Прочая детская литература
- Детская фантастика
- Детские стихи
- Детская образовательная литература
- Детские остросюжетные
- Учебная литература
- Зарубежные детские книги
- Детский фольклор
- Буквари
- Книги для подростков
- Школьные учебники
- Внеклассное чтение
- Книги для дошкольников
- Детская познавательная и развивающая литература
- Детские детективы
- Домоводство, Дом и семья
- Юмор
- Документальные книги
- Бизнес
- Работа с клиентами
- Тайм-менеджмент
- Кадровый менеджмент
- Экономика
- Менеджмент и кадры
- Управление, подбор персонала
- О бизнесе популярно
- Интернет-бизнес
- Личные финансы
- Делопроизводство, офис
- Маркетинг, PR, реклама
- Поиск работы
- Бизнес
- Банковское дело
- Малый бизнес
- Ценные бумаги и инвестиции
- Краткое содержание
- Бухучет и аудит
- Ораторское искусство / риторика
- Корпоративная культура, бизнес
- Финансы
- Государственное и муниципальное управление
- Менеджмент
- Зарубежная деловая литература
- Продажи
- Переговоры
- Личная эффективность
- Торговля
- Научные и научно-популярные книги
- Биофизика
- География
- Экология
- Биохимия
- Рефераты
- Культурология
- Техническая литература
- История
- Психология
- Медицина
- Прочая научная литература
- Юриспруденция
- Биология
- Политика
- Литературоведение
- Религиоведение
- Научпоп
- Психология, личное
- Математика
- Психотерапия
- Социология
- Воспитание детей, педагогика
- Языкознание
- Беременность, ожидание детей
- Транспорт, военная техника
- Детская психология
- Науки: разное
- Педагогика
- Зарубежная психология
- Иностранные языки
- Филология
- Радиотехника
- Деловая литература
- Физика
- Альтернативная медицина
- Химия
- Государство и право
- Обществознание
- Образовательная литература
- Учебники
- Зоология
- Архитектура
- Науки о космосе
- Ботаника
- Астрология
- Ветеринария
- История Европы
- География
- Зарубежная публицистика
- О животных
- Шпаргалки
- Разная литература
- Зарубежная литература о культуре и искусстве
- Пословицы, поговорки
- Боевые искусства
- Прочее
- Периодические издания
- Фанфик
- Военное
- Цитаты из афоризмов
- Гиды, путеводители
- Литература 19 века
- Зарубежная образовательная литература
- Военная история
- Кино
- Современная литература
- Военная техника, оружие
- Культура и искусство
- Музыка, музыканты
- Газеты и журналы
- Современная зарубежная литература
- Визуальные искусства
- Отраслевые издания
- Шахматы
- Недвижимость
- Великолепные истории
- Музыка, танцы
- Авто и ПДД
- Изобразительное искусство, фотография
- Истории из жизни
- Готические новеллы
- Начинающие авторы
- Спецслужбы
- Подростковая литература
- Зарубежная прикладная литература
- Религия и духовность
- Старинная литература
- Справочная литература
- Компьютеры и Интернет
- Блог
Язык программирования C++. Пятое издание - Стенли Липпман
Шрифт:
Интервал:
Закладка:
За одним исключением, рассматриваемым в разделе 17.4.2, типы распределения являются шаблонами с одним параметром типа шаблона, представляющим тип создаваемых распределением чисел. Эти типы всегда создают либо тип с плавающей точкой, либо целочисленный тип.
У каждого шаблона распределения есть аргумент шаблона по умолчанию (см. раздел 16.1.3). Типы распределения, создающие значения с плавающей точкой, по умолчанию создают значения типа double. Распределения, создающие целочисленные результаты, используют по умолчанию тип int. Поскольку у типов распределения есть только один параметр шаблона, при необходимости использовать значение по умолчанию следует не забыть расположить за именем шаблона пустые угловые скобки, чтобы указать на применение типа по умолчанию (см. раздел 16.1.3):
// пустые <> указывают на использование
// для результата типа по умолчанию
uniform_real_distribution<> u(0,1); // по умолчанию double
Создание чисел с неравномерным распределениемКроме корректного создания случайных чисел в заданном диапазоне, новая библиотека позволяет также получить числа, распределенные неравномерно. Действительно, библиотека определяет 20 типов распределений! Эти типы перечисляются в разделе А.3.
Для примера создадим серию нормально распределенных значений и нарисуем полученное распределение. Поскольку тип normal_distribution создает числа с плавающей запятой, данная программа будет использовать функцию lround() из заголовка cmath для округления каждого результата до ближайшего целого числа. Создадим 200 чисел с центром в значении 4 и среднеквадратичным отклонением 1,5. Поскольку используется нормальное распределение, можно ожидать любых чисел, но приблизительно 1% из них будет в диапазоне от 0 до 8 включительно. Программа подсчитает, сколько значений соответствует каждому целому числу в этом диапазоне:
default_random_engine е; // создает случайные целые числа
normal_distribution<> n(4,1.5); // середина 4, среднеквадратичное
// отклонение 1.5
vector<unsigned> vals(9); // девять элементов со значением 0
for (size_t i = 0; i != 200; ++i) {
unsigned v = lround(n(e)); // округление до ближайшего целого
if (v < vals.size()) // если результат в диапазоне
++vals[v]; // подсчитать, как часто встречается каждое число
}
for (size_t j = 0; j != vals.size(); ++j)
cout << j << ": " << string(vals[j], '*') << endl;
Начнем с определения объектов генератора случайных чисел и вектора vals. Вектор vals будет использован для расчета частоты создания каждого числа в диапазоне 0…9. В отличие от большинства других программ, использующих вектор, создадим его сразу с необходимым размером. Так, каждый его элемент инициализируется значением 0.
В цикле for происходит вызов функции lround(n(е)) для округления возвращенного вызовом n(е) значения до ближайшего целого числа. Получив целое число, соответствующее случайному числу с плавающей точкой, используем его для индексирования вектора счетчиков. Поскольку вызов n(е) может создавать числа и вне диапазона от 0 до 9, проверим полученное число на принадлежность диапазону прежде, чем использовать его для индексирования вектора vals. Если число принадлежит диапазону, увеличиваем соответствующий счетчик.
Когда цикл заканчивается, вывод содержимого вектора vals выглядит следующим образом:
0: ***
1: ********
2: ********************
3: **************************************
4: **********************************************************
5: ******************************************
6: ***********************
7: *******
8: *
Выведенные строки содержат столько звездочек, сколько раз встретилось соответствующее значение, созданное генератором случайных чисел. Обратите внимание: эта фигура не совершенно симметрична. Если бы она была симметрична, то возникли бы подозрения в качестве генератора случайных чисел.
Класс bernoulli_distributionКак уже упоминалось, есть одно распределение, которое не получает параметр шаблона. Это распределение bernoulli_distribution, являющееся обычным классом, а не шаблоном. Это распределение всегда возвращает логическое значение true с заданной вероятностью. По умолчанию это вероятность .5.
В качестве примера распределения этого вида напишем программу, которая играет с пользователем. Игру начинает один из игроков (пользователь или программа). Чтобы выбрать первого игрока, можно использовать объект класса uniform_int_distribution с диапазоном от 0 до 1. В качестве альтернативы этот выбор можно сделать, используя распределение Бернулли. С учетом, что игру начинает функция play(), для взаимодействия с пользователем может быть использован следующий цикл:
string resp;
default_random_engine e; // e имеет состояние, поэтому располагается
// вне цикла!
bernoulli_distribution b; // по умолчанию четность 50/50
do {
bool first = b(e); // если true, программа ходит первой
cout << (first ? "We go first"
: "You get to go first") << endl;
// играть в игру, угадывая, кто ходит первым
cout << ((play(first)) ? "sorry, you lost"
: "congrats, you won") << endl;
cout << "play again? Enter 'yes' or 'no'" << endl;
} while (cin >> resp && resp[0] == 'y');
Для повторного запроса на продолжение игры используем цикл do while (см. раздел 5.4.4).
Поскольку процессоры возвращают ту же последовательность чисел (см. раздел 17.4.1), их объявляют за пределами циклов. В противном случае при каждой итерации создавался бы новый процессор, выдающий каждый раз те же значения. Распределения также могут хранить состояние и также должны определяться вне циклов.
Одна из причин использования в этой программе распределения bernoulli_distribution заключается в том, что это предоставит программе лучший шанс пойти первой:
bernoulli_distribution b(.55); // предоставить программе небольшое
// преимущество
Такое определение b предоставит программе 55/45 шансов на первый ход.
Упражнения раздела 17.4.2Упражнение 17.31. Что случилось бы в программе игры данного раздела, будь объекты b и е определены в цикле do?
Упражнение 17.32. Что случилось бы, будь строка resp определена в цикле?
Упражнение 17.33. Напишите версию программы преобразования слова из раздела 11.3.6, допускающую несколько преобразований для заданного слова и случайно выбирающую применяемое преобразование.
17.5. Еще о библиотеке ввода и вывода
Глава 8 познакомила вас с базовой архитектурой и наиболее часто используемой частью библиотеки ввода-вывода. В этом разделе рассматриваются три более специализированных средства, поддерживаемых библиотекой ввода-вывода: управление форматом, не форматированный ввод-вывод и произвольный доступ.
17.5.1. Форматированный ввод и вывод
Кроме флага состояния (см. раздел 8.1.2), каждый объект iostream имеет также флаг формата, контролирующий подробности формата ввода и вывода. Флаг формата контролирует такие аспекты, как формат записи целочисленных значений, точность значений с плавающей запятой, ширина выводимого элемента и т.д.
Библиотека определяет набор перечисленных в табл. 17.17 и 17.18 манипуляторов (manipulator) (см. раздел 1.2), изменяющих флаг формата потока. Манипулятор — это функция или объект, влияющие на состояние потока и применяемые как операнд оператора ввода или вывода. Как и операторы ввода и вывода, манипулятор возвращает потоковый объект, к которому он применяется; таким образом, можно объединить манипуляторы и данные в один оператор.
Таблица 17.17. Манипуляторы, определенные в объекте iostream
boolalpha Отображать значения true и false как строки *noboolalpha Отображать значения true и false как 0 и 1 showbase Создавать префикс, означающий базу целочисленных значений *noshowbase Не создавать префикс базы чисел showpoint Всегда отображать десятичную точку для значений с плавающей запятой *noshowpoint Отображать десятичную точку, только если у значения есть дробная часть showpos Отображать + для положительных чисел *noshowpos Не отображать + в неотрицательных числах uppercase Выводить 0X в шестнадцатеричной и E в экспоненциальной формах записи *nouppercase Выводить 0x в шестнадцатеричной и е в экспоненциальной формах записи *dec Отображать целочисленные значения с десятичной базой числа hex Отображать целочисленные значения с шестнадцатеричной базой числа oct Отображать целочисленные значения с восьмеричной базой числа left Добавлять дополняющие символы справа от значения right Добавлять дополняющие символы слева от значения internal Добавлять дополняющие символы между знаком и значением fixed Отображать значения с плавающей точкой в десятичном представлении scientific Отображать значения с плавающей точкой в экспоненциальном представлении hexfloat Отображать значения с плавающей точкой в шестнадцатеричном представлении (нововведение С++11) defaultfloat Вернуть формат числа с плавающей точкой в десятичный (нововведение С++11) unitbuf Сбрасывать буфер после каждой операции вывода *nounitbuf Восстановить обычный сброс буфера *skipws Пропускать отступы в операторах ввода noskipws Не пропускать отступы в операторах ввода flush Сбросить буфер объекта ostream ends Вставить нулевой символ, а затем сбросить буфер объекта ostream endl Вставить новую строку, а затем сбросить буфер объекта ostream*Означает стандартное состояние потока

