В языке C++ контейнер set позволяет работать с различными множествами. Под множеством в данном случае понимают некоторое количество отсортированных элементов. Использование в файле set требует подключения
1 |
#include <set> |
В данном контейнере сортировка происходит автоматически, при добавлении элемента. Причем повторяющиеся элементы могут быть, как удалены, в случае работы с множеством, так и записаны, в случае с мультимножеством, позволяющим это. Рассмотрим конкретный пример
1 2 3 4 5 6 7 8 9 |
set<int> S; multiset<int> mS; mS.insert(1); mS.insert(2); mS.insert(2); S.insert(1); S.insert(2); S.insert(2); |
После добавлений мы получим 2 множества S = (1, 2) и mS = (1, 2, 2). Вместо insert можно использовать функцию emplace, которая перед добавлением проверяет, есть ли уже такой элемент, и если нет, то добавляет его.
Set является контейнером, так что имеет все стандартные для контейнера функции:
- Работа с элементами set:
- S.swap(S2) - меняет содержимое контейнеров местами,
- S.insert(a) - вставка элемента a,
- S.erase(S2) - удаляет последовательность элементов,
- S.clear() - очистка контейнера set,
- S.count() - количество элементов в контейнере,
- S.find(a) - найти элемент a в контейнере,
- S.lower_bound(a) - первый элемент, не меньший чем a,
- S.upper_bound(a) - первый элемент, больший чем a,
- S.equal_range(a) - пара элементов, первый - нижняя граница элементов с, такими же значениями, что и a, второй - верхняя граница элементов с такими же значениями, что и a.
- Работа с памятью:
- S.size() - размер контейнера,
- S.max_size() - максимальный размер контейнера.
- Работа с контейнером:
- S.begin() - указатель на начало контейнера,
- S.end() - указатель на конец контейнера,
- S.rbegin() - реверсивный указатель на конец контейнера,
- S.rend() - реверсивный указатель на начало контейнера.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
#include <set> // подключаем set #include <string> // подключаем строки string #include <iostream> // подключаем cout using namespace std; // чтобы не писать std:: int main() { set <string> S; // инициализация set S.insert("January"); S.insert("February"); S.insert("March"); S.insert("April"); cout<<S.size()<<'\n'; // будет выведено 4 cout<<S.max_size()<<'\n'; cout<<*(S.begin())<<'\n'; // April cout<<*(S.rbegin())<<'\n'; // March cout<<S.count("January")<<'\n'; // 1 cout<<*S.lower_bound("January")<<'\n'; // January cout<<*S.upper_bound("January")<<'\n'; // March cout<<*(S.equal_range("January")).first<<'\n'; // January cout<<*(S.equal_range("January")).second<<'\n'; // March cout<<*S.find("January")<<'\n'; // January S.erase("January"); cout<<S.count("January")<<'\n'; // 0 S.clear(); cout<<S.size()<<'\n'; // 0 cin.get(); // ожидаем нажатие пользователем клавиши return 0; // выдаём 0 - правило хорошего тона } |
Здравствуйте. Почему в 19 строке Март, а не Апрель?
"19 - cout<<*(S.rbegin())<<'\n'; // March"
Элементы упорядочиваются согласно алфавиту:
April, February, January, March
С++ не знает календарь. Так что последний - именно, March.
Здесь интереснее *(S.rend()). Он совпал с January, но вообще-то используется немного для другого. S.rend() - обратный итератор, указывающий на теоретический элемент непосредственно перед первым элементом в контейнере (который считается его обратным концом). Нужен S.rend(), чтобы можно было похожий цикл составить:
set<string>::reverse_iterator rit;
for (rit=S.rbegin(); rit != S.rend(); ++rit)
cout << ' ' << *rit; // March January February April