C++. Сборник рецептов - [106]
>back_inserter
(как использовать >back_inserter
, рассказывается в рецепте 7.5).Объявление >set_union
выглядит вот так.
>Out set_union(In first1, In last1, In first2, In last2, Out result);
Объявления >set_difference
, >set_intersection
и >set_symmetric_difference
выглядят точно так же.
Чтобы использовать эти функции, сделайте так, как показано в примере 7.8. Например, чтобы найти пересечение двух множеств, вызовите >set_intersection
вот так.
>set_intersection(s1.begin(), s1.end(), s2.begin(), s2.end(),
> inserter(setInter, setInter.begin()));
Последний аргумент >set_intersection
требует некоторых пояснений, >inserter
— это шаблон функции, определенный в >
, который принимает контейнер и итератор и возвращает выходной итератор, который при записи в него значения вызывает для первого аргумента >inserter
метод >insert
. При его использовании для последовательного контейнера он вставляет значения перед >iterator
, переданным в качестве второго аргумента. При его использовании для ассоциативного контейнера, как это делается в показанном выше фрагменте кода, этот итератор игнорируется, и элементы вставляются в соответствии с критерием сортировки контейнера.
>set
— это удобный пример для наших целей, но операции над множествами работают для любых последовательностей, а не только для >set
. Например, операции над множествами можно выполнить для >list
:
>list
>// Заполняем их данными
>lst1.sort(); // Элементы должны быть отсортированы
>lst2.sort();
>set_symmetric_difference(lst1 begin(), lst1.end(),
>lst2.begin(), lst2.end(), back_inserter(lst3));
Однако так как >list
хранит данные в неотсортированном виде, его вначале требуется отсортировать иначе результаты операций над множествами будут неверными. Также обратите внимание, что в этом примере вместо >inserter
используется >back_inserter
. >back_inserter
работает аналогично >inserter
, за исключением того, что для добавления элементов в контейнер он использует >push_back
. Вы не обязаны действовать точно так же. Например, можно изменить размер выходного контейнера так, чтобы он стал достаточно большим
>lst3.resize(lst1.size() + lst2.size()),
>set_symmetric_difference(lst1.begin(), lst1.end(),
> lst2.begin(), lst2.end(), lst3.begin())
;
Если выходная последовательность будет достаточно большой, то можно просто передать итератор, указывающий на первый элемент последовательности, используя >begin
.
Если вы не знаете, что такое >set_symmetric_difference
, я вам расскажу. Это объединение разностей двух множеств, определенных в прямом и обратном порядке. Это значит, что если а и b — это множества, то симметричная разность — это а - b b - а. Другими словами, симметричная разность — это множество всех элементов, которые присутствуют в одном из множеств, но отсутствуют в другом.
Есть еще один момент, который следует знать при работе с операциями над множествами. Так как последовательности не обязаны быть уникальными, можно получить «множество» с повторяющимися значениями. Конечно, строго математически множество не может содержать повторяющиеся значения, так что этот момент может быть не очевиден, Рассмотрим, как будет выглядеть вывод примера 7.8, если вместо >set
использовать >list
(при запуске примера 7.8 можно вводить повторяющиеся значения, но они не будут добавлены в >set
, так как >set::insert
не выполняется для элементов, которые уже присутствуют в >set
).
>Введите несколько строк: a a a b с с
>^Z
>Введите еще несколько строк: a a b b с
>^Z
>Объединение a a a b b с с
>Различие: a c
>Пересечение: a a b с
Здесь операции над множествами перебирают обе последовательности и сравнивают соответствующие значения, определяя, что следует поместить в выходную последовательность.
Наконец, операции над множествами в их оригинальном виде (использующие для сравнения элементов >operator<
) могут не работать так, как вам требуется, если последовательности содержат указатели. Чтобы обойти эту проблему, напишите функтор, который сравнивает объекты указателей, как в рецепте 7.4.
Рецепт 7.4.
7.9. Преобразование элементов последовательности
Имеется последовательность элементов, и с каждым элементом требуется выполнить какие-либо действия — либо на месте, либо скопировав их в другую последовательность.
Используйте стандартные алгоритмы >transform
или >for_each
. Они оба просты, но позволяют выполнить почти любые действия с элементами последовательностей. Пример 7.9 показывает, как это делается.
Пример 7.9. Преобразование данных
>#include
>#include
>#include
>#include
>#include
>#include
>#include
>#include "utils.h" // Для printContainer(): см. 7.10
>using namespace std;
>// Преобразуем строки к верхнему регистру
>string strToUpper(const string& s) {
> string tmp;
> for (string::const_iterator p = s.begin(); p != s.end(); ++p)
> tmp += toupper(*p);
> return(tmp);
>}
>string strAppend(const string& s1, const string& s2) {
> return(s1 + s2);
>}
>int main() {
> cout << "Введите несколько строк: ";
> istream_iterator
> istream iterator
> list
> // Используем преобразование с помощью унарной функции...
Java Enterprise Edition (Java EE) остается одной из ведущих технологий и платформ на основе Java. Данная книга представляет собой логичное пошаговое руководство, в котором подробно описаны многие спецификации и эталонные реализации Java EE 7. Работа с ними продемонстрирована на практических примерах. В этом фундаментальном издании также используется новейшая версия инструмента GlassFish, предназначенного для развертывания и администрирования примеров кода. Книга написана ведущим специалистом по обработке запросов на спецификацию Java EE, членом наблюдательного совета организации Java Community Process (JCP)
Разработчику часто требуется много сторонних инструментов, чтобы создавать и поддерживать проект. Система Git — один из таких инструментов и используется для контроля промежуточных версий вашего приложения, позволяя вам исправлять ошибки, откатывать к старой версии, разрабатывать проект в команде и сливать его потом. В книге вы узнаете об основах работы с Git: установка, ключевые команды, gitHub и многое другое.В книге рассматриваются следующие темы:основы Git;ветвление в Git;Git на сервере;распределённый Git;GitHub;инструменты Git;настройка Git;Git и другие системы контроля версий.
Рассмотрено все необходимое для разработки, компиляции, отладки и запуска приложений Java. Изложены практические приемы использования как традиционных, так и новейших конструкций объектно-ориентированного языка Java, графической библиотеки классов Swing, расширенной библиотеки Java 2D, работа со звуком, печать, способы русификации программ. Приведено полное описание нововведений Java SE 7: двоичная запись чисел, строковые варианты разветвлений, "ромбовидный оператор", NIO2, новые средства многопоточности и др.
Система сборки программ, используемая во FreeBSD, имеет значительно большие возможности, чем те, которые мы задействовали. Какие это возможности и как их использовать в своих портах?
Python - объектно-ориентированный язык сверхвысокого уровня. Python, в отличии от Java, не требует исключительно объектной ориентированности, но классы в Python так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.
«Как пасти котов» – это книга о лидерстве и руководстве, о том, как первое совмещать со вторым. Это, если хотите, словарь трудных случаев управления IT-проектами. Программист подобен кошке, которая гуляет сама по себе. Так уж исторически сложилось. Именно поэтому так непросто быть руководителем команды разработчиков. Даже если вы еще месяц назад были блестящим и дисциплинированным программистом и вдруг оказались в роли менеджера, вряд ли вы знаете, с чего надо начать, какой выбрать стиль руководства, как нанимать и увольнять сотрудников, проводить совещания, добиваться своевременного выполнения задач.