|
Программирование >> Разработка устойчивых систем
Конечно, без нарушения авторских прав. Проще всего начать с заголовочного файла <algorithm>, найти что-нибудь похожее на то, что вам нужно, и построить свой код по готовому образцу (практически во всех реализациях STL код шаблонов определяется непосредственно в заголовочных файлах). Если внимательнее изучить список алгоритмов стандартной библиотеки С++, можно заметить очевидное упущение: в нем отсутствует алгоритм copyJf(). Хотя желаемого эффекта можно добиться при помощи алгоритма remove copyJf(), это не так удобно, поскольку условие приходится инвертировать (вспомните: алгоритм remove copy if() копирует только те элементы, которые не соответствуют его предикату). Напрашивается очевидное решение - инвертировать предикат адаптером notl перед тем, как передавать его алгоритму remove copy if(): Pred -- исходное условие replace copyJf(begin. end. notl(pred)); Выглядит вполне разумно, но... Если мы хотим, чтобы наше решение поддерживало предикаты, которые являются указателями на обычные функции, становится понятно, почему оно не работает - адаптер notl ожидает получить адаптируемый объект функции. Остается лишь написать алгоритм copy if() с нуля . Изучение других алгоритмов копирования показывает, что на концептуальном уровне следует использовать разные итераторы для ввода и вывода, поэтому решение может выглядеть так: : C06:copy if.h Написание собственных алгоритмов в стиле STL #ifndef COPY IF H #def1ne COPY IF H tempiate<typename Forwardlter, typename Outputlter, typename UnaryPred> Outputlter copy if(Forwardlter begin. Forwardlter end. Outputlter dest. UnaryPred f) { while(begin != end) { if(f(*begin)) *dest++ = *begin; ++begin; return dest: #endif COPY IF H /:- Обратите внимание: инкремент begin не может интегрироваться в выражение копирования. Итоги Эта глава дает читателю практическое представление об алгоритмах стандартной библиотеки шаблонов. Иначе говоря, вы должны знать алгоритмы STL и разбираться в них достаточно хорошо, чтобы регулярно их использовать (или хотя бы учитывать возможность их применения, чтобы при необходимости вернуться к этой Упражнения Напищите генератор, который бы возвращал текущее значение с1оск() (из заголовка <ctime>). Создайте контейнер list<clock t> и заполните его своим генератором, используя алгоритм generate n(). Удалите все дубликаты из списка и выведите его в cout при помощи алгоритма сору(). Используя алгоритмы transform() и toupper() (из <cctype>), напишите вызов функции, который бы преобразовывал все символы строки к верхнему регистру. Создайте объект функции Sum, который бы накапливал сумму всех элементов в интервале при использовании с алгоритмом for each(). Напишите генератор анаграмм, который получает слово в командной строке и строит все возможные перестановки букв. Напишите программу, которая получает предложение в командной строке и строит все возможные перестановки (сами слова при этом остаются без изменений, меняется лишь их порядок). Создайте иерархию классов, состоящую из базового класса В и производного laiacca D. Определите в В виртуальную функцию void f(), которая выводит сообщение о вызове f() класса В. Переопределите эту функцию в D так, чтобы она выводила другое сообщение. Создайте вектор vector<B*>, заполните его объектами В и D, и при помощи алгоритма for each() вызовите f() для каждого объекта в векторе. Измените программу FunctionObjects.cpp так, чтобы вместо int в ней использовался тип float. Измените программу FunctionObjects.cpp и оформите основной код тестирования в виде шаблона, чтобы вы могли выбрать тестируемый тип (большую часть кода main() придется выделить в отдельную шаблонную функцию). Напишите программу, которая получает целое число в аргументе командной строки и находит все его множители. главе и найти подходящее рещение). Мощь библиотеки STL обусловлена не только относительной полнотой ее инструментария, но и тем, что она формирует концептуальный подход к рещению задач и созданию дополнительных инструментов. Хотя в этой главе приводятся примеры пользовательских расщирений STL, мы не стали подробно излагать весь теоретический материал, необходимый для полного понимания многочисленных тонкостей STL (хотя это позволило бы вам создавать программы гораздо соверщеннее тех, которые рассматривались в книге). Отчасти данное упущение объясняется нехваткой места, но это не главное. Основная причина все же заключается в том, что полное изложение материала выходит за рамки темы настоящей главы - мы лищь стремились дать практическое представление об STL, которое бы пригодилось вам в повседневной работе. Существует немало книг, полностью посвященных STL. Мы особенно рекомендуем вам книгу Скотта Мейерса Эффективное использование STL. Библиотека программиста , выщедщую в издательстве Питер в 2003 году. 10. Напишите программу, которая получает из командной строки имя тестового файла. Откройте файл и прочитайте его по словам (используйте оператор ). Сохраните слова в vector<string>. Преобразуйте все слова к нижнему регистру, отсортируйте их, удалите дубликаты и выведите результат. 11. Напишите программу для поиска всех слов, присутствующих одновременно в двух входных файлах (используйте алгоритм set intersection()). Затем измените ее так, чтобы она выводила все слова, присутствующие только в одном из файлов (используйте алгоритм set symmetric difference()). 12. Напишите программу, которая строит таблицу факториалов до числа, заданного в командной строке (включительно). Для этого напишите генератор, заполняющий вектор vector<int>, а затем воспользуйтесь алгоритмом partiaLsum() со стандартным объектом функции. 13. Измените программу Calclnventory.cpp для поиска всех объектов, количество которых меньше заданного порога, переданного в командной строке. Используйте алгоритмы copy if() и bind2nd() для построения набора всех значений, меньших заданного. 14. Сгенерируйте 100 чисел функцией UrandGen() (размер неважен). Определите, какие числа в этом интервале дают одинаковый остаток при делении на 23. Выберите случайное число и определите, входит ли оно в этот интервал; для этого разделите каждый элемент интервала на это число и проверьте, равен ли результат 1 (вместо простого поиска алгоритмом find()). 15. Заполните вектор vector<double> числами, представляющими углы в радианах. Используя механизм композиции объектов функций, вычислите синусы всех элементов вектора (см. файл <cmath>). 16. Оцените быстродействие вашего компьютера. Вызовите функцию srand(time(0)), создайте массив случайных чисел. Снова вызовите функцию srand(time(0)) и сгенерируйте такое же количество случайных чисел во втором массиве. При помощи алгоритма equal() проверьте, совпадает ли содержимое массивов (если ваш компьютер достаточно быстр, time(O) вернет одинаковые значения при обоих вызовах). Если массивы не совпадают, отсортируйте их и найдите различия алгоритмом mismatch(). Если их содержимое идентично, увеличьте длину массивов и попробуйте снова. 17. Напишите алгоритм transform if() в стиле STL. Возьмите за образец первую форму transform(), которая преобразует только объекты, удовлетворяющие унарному предикату. Объекты, не удовлетворяющие предикату, исключаются из результата. Алгоритм должен возвращать новый конечный итератор. 18. Создайте алгоритм в стиле STL, который бы представлял собой перегруженную версию алгоритма for each(). Алгоритм должен работать по образцу второй формы transform(): он должен получать два входных интервала и передавать объекты второго интервала бинарной функции, применяющей их к объектам первого интервала. 19. Создайте шаблон класса Matrix на базе вектора vector<vector<T . Определите дружественную операторную функцию ostream& operator (ostream&,const
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки. |