Иллюстрированный самоучитель по Visual Studio .NET

Контейнер типа set

Два отношения порядка для типов данных, хорошо вам знакомых (char и char*), для разнообразия заданы: одно в виде предиката, другое в виде функционального объекта. Ниже они будут использованы в конструкторе шаблона классов set. Тем самым определен порядок сортировки элементов контейнера:

void main ()
{
//====== Обычные неупорядоченные массивы символов
const int N = 6; const char* a[N] =
{
"Set", "Pet", "Net", "Get", "Bet", "Let"
};
const char* b[N] =
{
"Met", "Wet", "Jet",
"Set", "Pet", "Net",
};
//======== Создаем два множества обычных строк,
//======== определяя отношение порядка
set<const char*, LessStr> A(a, a + N);
set<const char*, LessStr> B(b, b + N);
//======== Создаем пустое множество
set<const char*, LessStr> C;
//======== Выходной итератор привязываем к cout
cout << "Set A: {";
copy (A.begin (), A.end.(),
ostream_iterator<const char*>(cout, "; "));
cout << ' } ';
cout << "\n\nSet B:
copy (B.begin (), B.end(),. .ostream_iterator<const char*>(cout, ", "));
//======= Создаем и выводим объединение двух множеств
cout << "\n\nUnion A U В: ";
set_union (A.begin (), A.end(), B.begin(), B.end(),
ostream_iterator<const char*>(cout, ", "),
LessStr ())';
//======= Создаем и выводим пересечение двух множеств
cout " "\n\nlntersection А & В: ";
set_intersection (A.begin (), A.end(), B.beginO, B.end(),
ostream_iterator<const char*>(cout, " "), LessStrO);
//===== Создаем разность двух множеств
//===== Используем inserter для заполнения множества С
set_dif ference (A.begin (), A.end(), B.beginO, B.end(),
inserter (С, C.begin()),
LessStr());
cout << "\n\nDifference A/B: ";
//===== Копируем множество прямо в выходной поток сору
С .begin (), С.
end ();
ostream_iterator<const char*>(cout, " "));
С .clear ();
//===== Повторяем в обратную сторону
set_dif ference (В .begin (), B.endO, A.begin(), A.end(),
inserter (С, C.begin()), LessStrO);
cout << "\n\nDifference B/A: ";
copy (C.begin (), C.end(),
ostream_iterator<const char*>(cout, " "));
cout << "\n\n";
//====== Выводим разделитель
vector<char> line(50, ' = ');
ostream_iterator<char> os(cout, "");
copy (line.begin О, line.endO, os);
//====== Обычные массивы символов
char D[] = { 'a', 'b', 'с', 'd', ' e', 'f' };
char E[] = { 'A', 'B', 'C1, 'G', 'H1, 'H' };
cout << "\n\nSet D: ";
for (int i=0; i<N; i++) cout << D[i] << ", ";
cout << "\n\nSet E: ";
for (int i=0; i<N; i + -i-)
cout << E[i]<<",";
cout << "\n\nSymmetric Difference D/E (nocase): ";
//====== Используем алгоритм set_symmetric_difference
//====== для обычных массивов символов
set_symmetric_difference(D, D + N, E, E + N,
ostream_iterator<char>(cout, " "), NoCase);
cout <<"\n\n"; }

Новые возможности STL, которые использованы в этом фрагменте, – это использование адаптера insert_iterator и копирование содержимого контейнера прямо в выходной поток (см. ostream_iterator). Вывод в поток осуществляется с помощью особого типа итератора ostream_iterator, который осуществляет форматируемый вывод объектов типа Т в указанный выходной поток (ostream). Шаблон класса ostream_iterator настраивается на тип данных, в нашем случае const char*, а затем char, и берет в качестве параметров объект потокового вывода (cout) и разделитель, который мы специально изменяем по ходу дела для того, чтобы вы его обнаружили.

Insert_iterator – это адаптер (настройщик) итератора, который настраивает операнд, являющийся мишенью операции. Присвоение с помощью (сквозь призму) такого итератора вставляет объект в контейнер, раздвигая его, то есть, используя метод insert. Он следит за текущей позицией в контейнере (insertion point) и производит вставку перед ней. Здесь вы, однако, должны учесть различную семантику операции вставки в различные типы контейнеров. Если это последовательность (sequence), то все происходит именно так, как только что было сказано, но если это сортируемый ассоциативный контейнер, то вы не можете управлять позицией вставки.

Для таких контейнеров указание места вставки служит лишь отправной точкой для поиска реальной позиции в контейнере. В результате вставки при выводе вы увидите упорядоченную по возрастанию ключа последовательность. Порядок вставки в сортируемые ассоциативные контейнеры не влияет на порядок элементов, который вы увидите на экране. Однако он может повлиять на эффективность процесса вставки.

Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.