На этом шаге мы рассмотрим пример использования множеств.
Следующая программа демонстрирует некоторые возможности множеств:
//--------------------------------------------------------------------------- #include <vcl.h> #include <iostream> #include <iterator> #include <set> #include <conio.h> //необходимо для getch() #pragma hdrstop //--------------------------------------------------------------------------- #pragma argsused using namespace std; std::string ToRus(const std::string &in) { char *buff = new char [in.length()+1]; CharToOem(in.c_str(),buff); std::string out(buff); delete [] buff; return out; } int main(int argc, char* argv[]) { // Тип коллекции: //- дубликаты запрещены //- элементы типа int //- сортировка па убыванию typedef set<int,greater<int> > IntSet; IntSet coll1; // Пустое множество // Вставка элементов в произвольном порядке coll1.insert(4); coll1.insert(3); coll1.insert(5); coll1.insert(1); coll1.insert(6); coll1.insert(2); coll1.insert(5); // Перебор и вывод всех элементов IntSet::iterator pos; cout << ToRus("Элементы множества:\n"); for (pos = coll1.begin();pos != coll1.end(); ++pos) { cout << *pos << ' '; } cout << endl; // Попытка повторной вставки значения 4 // и обработка возвращаемого значения pair<IntSet::iterator,bool> status = coll1.insert(4); if (status.second) { cout << "4 inserted as element " << distance(coll1.begin(),status.first) + 1 << endl; } else { cout << ToRus("Число 4 уже есть") << endl; } // Присваивание элементов другому множеству, // упорядоченному по возрастанию set<int> coll2(coll1.begin(),coll1.end()); // Вывод всех элементов копии cout << ToRus("Элементы копии множества:\n"); copy (coll2.begin(), coll2.end(), ostream_iterator<int>(cout," ")); cout << endl; // Удаление всех элементов до элемента со значением 3 coll2.erase(coll2.begin(),coll2.find(3)); // Удаление всех элементов со значением 5 int num; num = coll2.erase(5); cout << num << ToRus(" элемент(ы) удален(ы)") << endl; // Вывод всех элементов cout << ToRus("Элементы множества после удаления:\n"); copy (coll2.begin(),coll2.end(), ostream_iterator<int>(cout," ")); cout << endl; getch(); return 0; } //---------------------------------------------------------------------------
Сначала определение типа создает сокращенное имя типа для множества целых чисел, упорядоченного по убыванию:
typedef set<int,greater<int> > IntSet;
Затем мы создаем пустое множество и вставляем в него несколько элементов функцией insert():
IntSet coll1; // Пустое множество // Вставка элементов в произвольном порядке coll1.insert(4); coll1.insert(3); coll1.insert(5); coll1.insert(1); coll1.insert(6); coll1.insert(2); coll1.insert(5);
Обратите внимание: элемент со значением 5 вставляется дважды. Вторая вставка игнорируется, поскольку дубликаты в множествах запрещены.
После вывода всех элементов программа снова пытается вставить элемент 4. На этот раз возвращаемое значение функции insert() обрабатывается способом, упомянутым на 164 шаге.
Следующая команда создает новое множество элементов типа int, упорядоченных по возрастанию, и инициализирует его элементами прежнего множества:
set<int> coll2(coll1.begin(),coll1.end());
Контейнеры используют разные критерии сортировки, поэтому их типы различаются, а прямое присваивание или сравнение невозможно. Тем не менее алгоритмы обычно способны работать с разными тинами контейнеров, если типы их элементов совпадают или могут быть преобразованы друг к другу.
Следующая команда удаляет все элементы, предшествующие элементу со значением 3:
coll2.erase(coll2.begin(),coll2.find(3));
При этом элемент со значением 3 находится на открытом конце интервала и поэтому не удаляется.
Наконец, из контейнера удаляются все элементы со значением 5:
int num;
num = coll2.erase(5);
Результат выполнения программы выглядит так:
Рис.1. Результат работы приложения
На следующем шаге мы рассмотрим эту же программу, но вместо множества используем мультимножество.