Операции вставки и удаления элементов

Операция Назначение
s.insert(elem) Вставляет копию elem и возвращает позицию нового элемента; для множеств также возвращается признак успешного выполнения операции
s.insert(pos,elem) Вставляет копию elem и возвращает позицию нового элемента (pos определяет рекомендуемую позицию, с которой следует начинать поиск позиции вставляемого элемента)
s.insert(beg,end) Вставляет копию всех элементов интервала [beg,end) (и не возвращает значения)
s.insert(initlist) Вставляет копию всех элементов списка инициализации initlist (не возвращает ничего) (стандарт С++ 11)
s.erase(elem) Удаляет все элементы со значением elem и возвращает количество удаленных элементов
s.erase(pos) Удаляет элемент в позиции ите-ратора pos и возвращает сле-дующую позицию (до стандарта С++ 11 не возвращал ничего)
s.erase(beg,end) Удаляет все элементы из интервала [beg,end) и возвращает следующую позицию (до стандарта С++ 11 не возвращал ничего)
s.clear() Удаляет все элементы (контейнер остается пустым)

 

Рассмотрим пример программы, демонстрирующей операции с множествами:

//Листинг 27.2

#include<iostream>

#include<set>

#include<iterator>

using namespace std;

int main() {

/* Тип коллекции:

* - дубликаты запрещены

* - элементы типа 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;

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<<"4 already exists"<<endl;}

// Присваивание элементов другому множеству,

// упорядоченному по возрастанию

set<int> coll2(coll1.begin(),coll1.end());

// Вывод всех элементов копии

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<<" element(s) removed" << endl;

// Вывод всех элементов

copy(coll2.begin(),coll2.end(),

ostream_iterator<int>(cout," "));

cout<<endl;

return 0;

}

Результаты выполнения программы:

6 5 4 3 2 1

4 already exists

1 2 3 4 5 6

1 element(s) removed

3 4 6

Сначала определение типа создает сокращенное имя типа для множества целых чисел, упорядоченного по убыванию:

typedef set<int.greater<int> > IntSet;

Затем создается пустое множество и вставляется в него несколько элементов функцией insert():

IntSet coll1;

coll1.insert(4);

Элемент со значением 5 вставляется дважды. Вторая вставка игнорируется, поскольку дубликаты в множествах запрещены.

После вывода всех элементов программа снова пытается вставить элемент 4.

Следующая команда создает новое множество элементов типа int, упорядоченных по возрастанию, и инициализирует его элементами прежнего множества:

set<int> coll2(coll1.begin(),coll1.end());

Контейнеры используют разные критерии сортировки, поэтому их типы различаются, а прямое присваивание или сравнение невозможно. Тем не менее алгоритмы обычно способны работать с разными тинами контейнеров, если типы их элементов совпадают или могут быть преобразованы друг к другу.

Следующая команда удаляет все элементы, предшествующие элементу со значением 3:

col12.erase (col12.begin(),col12.find(3));

При этом элемент со значением 3 находится на открытом конце интервала и поэтому не удаляется.

В конце программы из контейнера удаляются все элементы со значением 5:

int num;

num = coll2.erase(5);

cout <<num<<" element(s) removed"<<endl;

 

Для мультимножеств эта программа выглядит несколько иначе и выводит другие результаты:

//Листинг 27.3

#include <iostream>

#include <set>

#include<iterator>

using namespace std;

int main() {

/* Тип коллекции;

* - дубликаты разрешены

* - элементы типа int

* - сортировка по убыванию */

typedef multiset<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;

for(pos= coll1.begin();pos!=coll1.end();

++pos)

{ cout<<*pos<<' ';}

cout<<endl;

// Повторная вставка значения 4

//и обработка возвращаемого значения

IntSet::iterator ipos = coll1.insert(4);

cout << "4 inserted as element "

<<distance(coll1.begin(),ipos)

+1 <<endl;

// Присваивание элементов другому множеству.

// упорядоченному по возрастанию

multiset<int> coll2(coll1.begin(),

coll1.end());

// Вывод всех элементов копии

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 << " element(s) removed"

<< endl;

// Вывод всех элементов

copy(coll2.begin(),coll2.end(),

ostream_iterator<int>(cout," "));

cout << endl;

return 0;

}

Результат выполнения программы:

6 5 5 4 3 2 1

4 inserted as element 5

1 2 3 4 4 5 5 6

2 element(s) removed

3 4 4 6

 

Тип set везде заменен типом multiset. Кроме того, возвращаемое значение функции insert() обрабатывается иначе:

IntSet::iterator ipos = coll1.insert(4);

cout <<"4 inserted as element "

<< distance(colll.begin().ipos)

+1<<endl;

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

 

Рассмотрим следующую задачу:

Заданы три множества, элементами которых могут быть следующие числа {1, 3, 5, 7, 9}.

Определить:

  1. Какие числа принадлежат всем трем множествам?
  2. Какие числа принадлежат хотя бы одному множеству?
  3. Какие числа из допустимых не принадлежат ни одному из множеств?

Написать программу на языке С++, в которой используется ассоциативный контейнер STL множество и его операции.

Решение задачи:

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

В программе будем работать с объектами класса set<mn> и определим следующие функции:

- функция vvod(), предназначенная для заполнения множества случайным образом. В качестве параметра функции передается ссылка на set<mn>, функция ничего не возвращает. Для генерации случайных чисел используется функция rand(), а для добавления подходящего элемента в множество операция insert();

- функция output (), имеющая один параметр типа set<mn>, выводящая на экран содержимое множества или соответствующее сообщение, если множество пусто. Вывод осуществляется с помощью итератора. Для проверки множества на пустоту используется операция empty().

- функция f1(), определяющая элементы, при-надлежащие всем трем множествам. Функция имеет три параметра типа set<mn>. Выводит на экран либо элементы, либо сообщение, если элементов нет. Для определения принадлежности элемента множеству используется операция count(elem), возвращающая 1, если elem принадлежит множеству, и 0 в противном случае.

- аналогичные функции: f2(), определяющая элементы, принадлежащие хотя бы одному множеству, и f3(), определяющая какие допустимые числа не являются элементами ни одного множества.

В функциях f1(), f2() и f3() используются логические операции.

В функции main() создаются три множества, случайным образом заполняются, выводятся на экран. Демонстрируется работа функций f1(), f2() и f3(), которым в качестве параметров передаются эти три множества.

//Листинг 27.4

#include<iostream>

#include<time.h>

#include<set>

using namespace std;

 

//определяем числа

//которые могут быть элементами множества

enum mn { one = 1, three = 3, five=5, seven=7,

nine=9};

 

//функция заполнения множества

//случайным образом

void vvod(set<mn> &s)

{

int n, m;

n = rand() * 30 / RAND_MAX + 1;

 

for (int i = 1; i <= n; ++i)

{

m = rand() * 9 / RAND_MAX + 1;

if (m % 2!= 0) s.insert((mn)m);

}

}

 

//функция вывода на экран элементов множества

void output(set<mn> s)

{

if (s.empty())

cout << "Множество пусто"<< endl;

else

for(auto ptr=s.begin(); ptr!= s.end();

++ptr)

cout << *ptr << " ";

cout << endl;

}

 

//функция, определяющая элементы,

// принадлежащие всем множествам

void f1(set<mn> s1, set<mn> s2, set<mn> s3)

{

int count = 0;

for (int i = 1; i <= 9; i += 2)

if (s1.count((mn)i) && s2.count((mn)i) &&

s3.count((mn)i))

{

cout << i << " ";

++count;

}

if (count == 0) cout << "Элементов нет";

cout << endl;

}

 

//функция, определяющая элементы,

//принадлежащие хотя бы одному множеству

void f2(set<mn> s1, set<mn> s2, set<mn> s3)

{

int count = 0;

for (int i = 1; i <= 9; i += 2)

if (s1.count((mn)i) || s2.count((mn)i) ||

s3.count((mn)i))

{

cout << i << " ";

++count;

}

if (count == 0) cout << "Элементов нет";

cout<<endl;

}

 

//функция, определяющая какие допустимые числа

//не являются элементами ни одного множества

void f3(set<mn> s1, set<mn> s2, set<mn> s3)

{

int count = 0;

for (int i = 1; i <= 9; i += 2)

if ((s1.count((mn)i) || s2.count((mn)i) ||

s3.count((mn)i)) == 0)

{

cout << i << " ";

++count;

}

if (count == 0) cout << "Чисел нет";

cout << endl;

}

int main()

{

setlocale(LC_ALL, "Russian");

srand(time(NULL));

//создаем три множества

set<mn> s1, s2, s3;

//заполняем множества случайным образом

vvod(s1);

vvod(s2);

vvod(s3);

//выводим на экран элементы трех множеств

cout << "Множество 1:" << endl;

output(s1);

cout << "Множество 2:" << endl;

output(s2);

cout << "Множество 3:" << endl;

output(s3);

cout <<

"Элементы,принадлежащие всем множествам:"

<< endl;

f1(s1, s2, s3);

cout <<

"Элементы, принадлежащие хотя бы одному

множеству:" << endl;

f2(s1, s2, s3);

cout << "Допустимые числа, не принадлежащие

ни одному множеству:" << endl;

f3(s1, s2, s3);

return 0;

}

Результаты выполнения программы:

Запуск 1:

Множество 1:

3 7 9

Множество 2:

Множество пусто

Множество 3:

1 3 5 7 9

Элементы, принадлежащие всем множествам:

Элементов нет

Элементы, принадлежащие хотя бы одному множеству:

1 3 5 7 9

Допустимые числа, не принадлежащие ни одному множеству:

Чисел нет

Запуск 2:

Множество 1:

3 5 7 9

Множество 2:

Множество 3:

5 7 9

Элементы, принадлежащие всем множествам:

Элементы, принадлежащие хотя бы одному множеству:

3 5 7 9

Допустимые числа, не принадлежащие ни одному множеству:

Задание:

Написать программу на языке С++. Использовать множества/мультимножества подходящего типа. Для выполнения операций с множествами/мультимножествами воспользоваться алгоритмами работы с множествами/мультимножествами из STL.

Вариант 1

В системе связи можно одновременноиспользовать несколькоаналогово-цифровых преобразователей (АЦП) разных типов. Типы АЦП могут быть следующими: параллельные прямого преобразования, параллельно-последовательные прямого преобразования, конвейерные, последовательные прямого преобразования, дифференциального кодирования. Были созданы три системы связи.

Определить: какого типа АЦП используются во всех системах связи; какого типа АЦП используются хотя бы в одной системе связи; какого типа АЦП не используются ни в одной системе связи.

Вариант 2

Дан текст из цифр и строчных латинских букв, за которыми следует точка. Определить, каких букв — гласных или согласных — больше в этом тексте; вывести в алфавитном порядке все согласные буквы, которые входят только в одно слово.

Вариант 3

В системе связи можно одновременноиспользовать несколькоцифро-аналоговых преобразователей (ЦАП) разных типов. Типы ЦАП могут быть следующими: широко-импульсный модулятор, передискретизации, взвешивающего типа, лестничного типа. Были созданы три системы связи.

Определить: какого типа ЦАП используются во всех системах связи; какого типа ЦАП используются только в одной системе связи; какого типа ЦАП используются хотя бы в двух системах связи.

Вариант 4

Дан текст из строчных латинских букв, за которыми следует точка. Вывести все буквы, входящие в текст не менее двух раз; все согласные буквы, входящие только в одно слово.

Вариант 5

В системе связи можно одновременноиспользовать кабель связи «витая пара» с различным материалом изоляции. Материал изоляции может быть следующим: поливинилхлорид, полипропилен, полиэтилен, вспененный полиэтилен, тефлон. Были созданы четыре системы связи.

Определить какой материал изоляции не использовался ни в одной системе; какой материал изоляции использовался хотя бы в двух системах связи; какой материал изоляции использовался только в одной системе связи.

Вариант 6

Дан текст на русском языке. Вывести в алфавитном порядке все гласные буквы, присутствующие в каждом слове; все согласные, которые не входят хотя бы в одно слово.

Вариант 7

В системе связи можно одновременноиспользовать волоконно-оптический кабель с различным материалом изготовления сердцевины. Материал изготовления сердцевины может быть следующим: кварцевое стекло, фторцирконат, фторалюминат, халькогенидные стекла, полиметилметакрилат. Были созданы три системы связи.

Определить какой материал сердцевины использовался во всех системах связи; какой материал сердцевины использовался только в двух системах связи; какой материал сердцевины не использовался ни в одной системе связи.

Вариант 8

Дан текст на русском языке. В алфавитном порядке вывести все гласные буквы (а, е, ё, и, й, о, у, ы, э, ю, я), входящие в этот текст более двух раз; все согласные, которые входят только в одно слово.

Вариант 9

В системе связи можно одновременноиспользовать коаксиальный кабель с различным материалом внутреннего проводника. Материал изготовления внутреннего проводника может быть следующим: медь, алюминиевый сплав, омеднённая сталь, омеднённый алюминий, посеребрённая медь. Были созданы три системы связи.

Определить какой материал внутреннего проводника использовался во всех системах связи; какой материал внутреннего проводника использовался только в двух системах связи; какой материал внутреннего проводника использовался только в одной системе связи.

Вариант 10

Дан текст из строчных латинских букв, за которыми следует точка. Вывести все буквы, входящие в текст по одному разу; все согласные, которые входят в каждое слово.

Вариант 11

В системе связи можно одновременноиспользовать кабель связи «витая пара» с различным типом конструкции экрана. Тип конструкции экрана может быть следующим: U/UTP, F/UTP, S/UTP, SF/UTP, F/FTP, S/FTP, SF/FTP. Были созданы три системы связи.

Определить какой тип экрана не использовался ни в одной системе; какой тип экрана использовался хотя бы в двух системах связи; какой тип экрана использовался хотя бы в одной системе связи.

Вариант 12

Дан текст на русском языке. Вывести в алфавитном порядке все согласные буквы, не найденные ни в одном слове; все гласные буквы, которые входят в текст более двух раз.

Вариант 13

В системе связи можно одновременноиспользовать коаксиальный кабель с различным материалом изоляции. Материал изоляции может быть следующим: полиэтилен, вспененный полиэтилен, сплошной фторопласт, фторопластовая лента, кордельно-трубчатый повив, шайбы. Были созданы четыре системы связи.

Определить какой материал изоляции использовался во всех системах связи; какой материал изоляции использовался только в трех системах связи; какой материал использовался хотя бы в одной системе связи.

Вариант 14

Дан текст на русском языке. Вывести в алфавитном порядке все согласные буквы, не найденные ни в одном слове; все гласные буквы, которые входят в текст более двух раз.

Вариант 15

Дан текст на русском языке. Вывести в алфавитном порядке все звонкие согласные буквы, которые найдены хотя бы в одном слове; все гласные буквы, которые не входят только в одно.

 


РЕКОМЕНДУЕМАЯ ЛИТЕРАТУРА

 

1. Дейтел Х.М., Дейтел П.Дж. Как программировать на С++. –М.: Бином-Пресс, 2011. – 1456 с.

2. Джосаттис Н.М. Стандартная библиотека С++: справочное руководство, 2-е изд. – М.: ООО «И.Д.Вильямс», 2014. -1136 с.

3. Клюшин Д.А. Полный курс C++. Профессиональная работа. – М.: Издательский дом «Вильямс», 2004. – 672 с.

4. Лаптев В.В. С++. Объектно-ориентированное програм-мирование. Учебное пособие. – СПб.: Питер, 2008. – 464 с.

5. Лаптев В.В., Морозов А.В., Бокова А.В. С++. Объектно-ориентированное программирование. Задачи и упражнения. – Спб.: Питер, 2007. – 288 с.

6. Леен Аммерааль STL для программистов на С++. – М.: ДМК Пресс, 2002. – 240 с.

7. Мюссер Д.Р., Дердж Ж.Дж., Сейни А. С++ и STL: справочное руководство. – М.:ООО «И.Д.Вильямс», 2010. – 432 с.

8. Павловская Т.А. С/С++. Процедурно и объектно-ориентированное программирование. Учебник для вузов. - СПб.: Питер, 2015. - 496 с.

9. Подбельский В.В. Стандартный Си++. Учебное пособие. – М.: Финансы и статистика, 2008. – 688 с.

10. Прата С. Язык программирования С++. Лекции и упражнения. – М.: Издательский дом «Вильямс», 2015. – 1244 с.

11. Шилдт Г. C++: базовый курс. – М.: Издательский дом «Вильямс», 2015. – 624 с.

12. Шилдт Г. Полный справочник по C++. – М.: Издательство Вильямс, 2014. – 795 с.

 


СОДЕРЖАНИЕ

Практическое занятие 1. Работа с последовательными контейнерами вектор и двусторонняя очередь. 3

Практическое занятие 2. Работа со списками в STL. 33

Практическое занятие 3. Ассоциативные контейнеры: множество и мультимножество. 71

РЕКОМЕНДУЕМАЯ ЛИТЕРАТУРА.. 96

 

 

 


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: