Стандартная библиотека шаблонов STL




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

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

Библиотека содержит пять основных видов компонентов:

· алгоритм (algorithm): определяет вычислительную процедуру.

· контейнер (container): управляет набором объектов в памяти.

· итератор (iterator): обеспечивает для алгоритма средство доступа к содержимому контейнера.

· функциональный объект (function object): инкапсулирует функцию в объекте для использования другими компонентами.

· - адаптер (adaptor): адаптирует компонент для обеспечения различного интерфейса.

Все контейнеры, предоставляемые STL, можно разделить на категории:

· непрерывные хранилища;

· списки;

· деревья поиска;

· хеш-таблицы;

· адаптеры контейнеров.

Рассмотрим подробнее контейнеры, используемые в данном курсовом проекте.

Контейнер std::list представляет собой классический двухсвязный список. Хотя к элементам списка нельзя обращаться произвольно, как в векторе STL, список способен организовать элементы в разделах, состоящих из нескольких участков, несмежных
в памяти. Поэтому у контейнера std::list нет присущих вектору проблем с производительностью, связанных с перераспределением его внутреннего массива.

Если необходимо выполнять обход списка только в одном направлении, то больше подойдет контейнер std::forward_list — он быстрее работает и занимает меньше места, поскольку в нем хранятся лишь указатели на следующий элемент. Пройти список можно только последовательно, за время O(n). Вставку и удаление элементов в заданную позицию можно выполнить за время O(1).

Контейнер std::multimap является частным случаем контейнера std::map, для которого отсутствует требование уникальности ключей.


 

ПРОЕКТНО-КОНСТРУКТОРСКАЯ ЧАСТЬ

Программа 1

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

 

Создаю шаблон для просмотра содержимого контейнера. auto е - инициализация переменной, тип которой определяется из значения присваиваемого выражения. В данном случае присваивается Input.cbegin() (который возвращает итератор на начало строки).

template <typename T>

void show_mmap(const T& Input)

{

for (auto e = Input.cbegin(); e!= Input.cend(); ++e)

{

cout << e->first << " -> " << e->second << endl;

}

cout << endl;

}

Создаю первый контейнер (mymap) и добавляю в него 4 пары «ключ - значение».

mymap.insert(make_pair(1, "element1"));

mymap.insert(make_pair(2, "element2"));

mymap.insert(make_pair(3, "element3"));

mymap.insert(make_pair(4, "element4"));

Просматриваю содержимое контейнера с помощью функции show_mmap().

Добавляю в контейнер еще одну пару «ключ – значение», причем «ключу» нового элемента присваиваю значение 4.

mymap.insert(make_pair(4, "element44"));

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

Чтобы убедиться в том, что в контейнер добавился новый элемент, снова использую функцию show_mmap().

Далее удаляю все элементы контейнера с ключом 4 (в контейнере два таких элемента).

auto NumErase = mymap.erase(4);

Просматриваю содержимое контейнера, используя для цикл for и итератор (it).

multimap <int, string>::iterator it = mymap.begin();

cout << "Контейнер 1: " << endl;

for (it; it!= mymap.end(); it++) {

cout << it->first << " - " << it->second << endl;

}

cout << endl;

Создаю второй контейнер и добавляю в него 4 значения.

mymap2.insert(make_pair(11, "number1"));

mymap2.insert(make_pair(22, "number2"));

mymap2.insert(make_pair(33, "number3"));

mymap2.insert(make_pair(44, "number4"));

Изменяю первый контейнер. Удаляю из него n элементов (число n вводится с клавиатуры). Использую созданный ранее итератор it.

int n;

cout << "Количество элементов, которые будут удалены: ";

cin >> n;

it = mymap.begin();

advance(it, n);

mymap.erase(mymap.begin(), it);

Следующим шагом добавляю в измененный первый контейнер (mymap) все элементы второго контейнера (mymap2).

mymap.insert(mymap2.begin(),mymap2.end());

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

show_mmap(mymap);

show_mmap(mymap2);


 

Программа 2

В соответствии с заданием создаю класс address. Объектами класса являются: name (имя, проживающего по данному адресу), street (название улицы), number (номер дома). Добавляю конструктор без параметров и конструктор с параметрами.

class adress {

public:

string name;

string street;

int number;

 

adress() //создаю конструктор без параметров

{

name = ""; street = ""; number = 0;

}

adress(string NAME, string STREET, int NUMBER) //создаю конструктор с параметрами

{

name = NAME; street = STREET; number = NUMBER;

}

 

};

Перегружаю оператор >> (istream) и оператор << (ostream).

istream& operator>> (istream& is, adress& adr)//перегружаю оператор >>

{

is >> adr.name;

is >> adr.street;

is >> adr.number;

return is;

}

 

ostream& operator<<(ostream& os, const adress& adr) { // Перегружаю оператор <<

return os << adr.name << " " << adr.street << " " << adr.number;

}

Создаю функцию замены элементов (Zam_el).

void Zam_el(int number_zamena, adress zn, multimap<int, adress>& mm)

{

mm.find(number_zamena)->second = zn;

}

Создаю первый контейнер (mymap) и итератор (it).

multimap<int, adress> mymap;

multimap<int, adress>::iterator it;

В текстовый файл «container_1.txt» записываю данные, которые будет храниться в контейнере mymap.

Считываю и переношу все данные из текстового файла «container_1.txt» в контейнер mymap, используя циклы while и for.

while (getline(schit, adress_2))

{

for (int i = 0; i < 2; i++)

{

v = adress_2.find(";", v);

endV[i] = v;

v = v + 1;

}

v = 0;

adress newAdress;

newAdress.name = adress_2.substr(0, endV[0]);

newAdress.street = adress_2.substr(endV[0] + 1, endV[1] - endV[0] - 1);

newAdress.number = stoi(adress_2.substr(endV[1] + 1, adress_2.length()));

mymap.emplace(keycount, newAdress);

keycount = keycount + 1;

}

schit.close();

Просматриваю содержимое контейнера mymap с помощью цикла for и итератора it.

for (it = mymap.begin(); it!= mymap.end(); it++)

{

cout << it->first << " - " << it->second << endl;

}

Удаляю два элемента контейнера (элемент с ключом 3, элемент с ключом 5).

mymap.erase(3); mymap.erase(5);

Создаю два новых объекта класса adress и заменяю ими элементы с ключами 2, 4.

adress ZamAd("Evgeniy(zamena)", "Pokrovsaya", 34);

Zam_el(2, ZamAd, mymap);

adress ZamAd2("Olga(zamena)", "Minina", 15);

Zam_el(4, ZamAd2, mymap);

После изменений просматриваю содержимое контейнера, используя цикл for и итератор it.

for (it = mymap.begin(); it!= mymap.end(); it++)

{

cout << it->first << " - " << it->second << " " << endl;

}

Создаю второй контейнер (mymap2) класса adress, создаю итератор.

multimap<int, adress> mymap2;

multimap<int, adress>::iterator it2;

В текстовый файл «container_2» записываю данные, которые будут переданы во второй контейнер (mymap2).

while (getline(schit2, adres2))

{

for (int i = 0; i < 2; i++)

{

v = adres2.find(";", v);

endV[i] = v;

v = v + 1;

}

v = 0;

adress newAdress;

newAdress.name = adres2.substr(0, endV[0]);

newAdress.street = adres2.substr(endV[0] + 1, endV[1] - endV[0] - 1);

newAdress.number = stoi(adres2.substr(endV[1] + 1, adres2.length()));

mymap2.emplace(keycount, newAdress);

keycount = keycount + 5;

}

schit2.close();

Изменяю первый контейнер, удалив из него n элементов после заданного.

for (it = mymap.begin(); it!= mymap.end(); it++)

{

if ((n > 0) && (schet > numzam))

{

it = mymap.erase(it);

--it;

n = n - 1;

}

schet = schet + 1;

}

Затем добавляю в него все элементы из второго контейнера.

for (it2 = mymap2.begin(); it2!= mymap2.end(); it2++)

{

mymap.insert(*it2);

}

Просматриваю содержимое контейнеров.

for (it = mymap.begin(); it!= mymap.end(); it++)

{

cout << it->first << " - " << it->second << " " << endl;;

}

cout << endl;

for (it2 = mymap2.begin(); it2!= mymap2.end(); it2++)

{

cout << it2->first << " - " << it2->second << " " << endl;

}


 

Программа 3

В соответствии с заданием создаю класс address. Объектами класса являются: name (имя, проживающего по данному адресу), street (название улицы), number (номер дома). Добавляю конструктор без параметров и конструктор с параметрами.

class adress {

public:

string name;

string street;

int number;

 

adress() //конструктор без параметров

{

name = ""; street = ""; number = 0;

}

adress(string NAME, string STREET, int NUMBER) //конструктор с параметрами

{

name = NAME; street = STREET; number = NUMBER;

}

 

};

Перегружаю операторы «<», «>>», «<<».

bool operator < (const adress& adr1, const adress& adr2) {

return adr1.number < adr2.number;

}

istream& operator>> (istream& is, adress& adr)

{

is >> adr.name;

is >> adr.street;

is >> adr.number;

return is;

}

ostream& operator<<(ostream& os, const adress& adr) {

return os << adr.name << " " << adr.street << " " << adr.number;

}

Для функции сортировки по убыванию создаю два контейнера «vector», и два итератора.

void sort_u(multimap<int, adress>& mumap)

{

vector<int> num_vec;

vector<adress> sort_vec;

vector<adress>::iterator it;

map<int, adress>::iterator mult_it;

int i = 0;

 

for (mult_it = mumap.begin(); mult_it!= mumap.end(); mult_it++)

{

num_vec.push_back(mult_it->first);

sort_vec.push_back(mult_it->second);

}

 

sort(sort_vec.begin(), sort_vec.end(), comp);

 

for (it = sort_vec.begin(); it < sort_vec.end(); it++)

{

mumap.find(num_vec[i])->second = *it;

i = i + 1;

}

 

}

Похожие действия выполняю для создания функции сортировки по убыванию.

void VozrSort(multimap<int, adress>& m_map)

{

vector<int> zn_vec;

vector<adress> sort_vec;

vector<adress>::iterator it;

map<int, adress>::iterator mult_it;

int i = 0;

 

for (mult_it = m_map.begin(); mult_it!= m_map.end(); mult_it++)

{

zn_vec.push_back(mult_it->first);

sort_vec.push_back(mult_it->second);

}

 

sort(sort_vec.begin(), sort_vec.end());

 

for (it = sort_vec.begin(); it < sort_vec.end(); it++)

{

m_map.find(zn_vec[i])->second = *it;

i = i + 1;

}

 

}

Создаю функцию поиска элементов

void Search(multimap<int, adress> m_map, adress add)

{

vector<adress> vec_1;

vector<adress>::iterator it;

map<int, adress>::iterator mult_it;

int i = 0;

 

for (mult_it = m_map.begin(); mult_it!= m_map.end(); mult_it++)

{

vec_1.push_back(mult_it->second);

}

 

sort(vec_1.begin(), vec_1.end(), comp);

if (binary_search(vec_1.begin(), vec_1.end(), add, comp))

cout << "Элемент был найден";

else

cout << "Элемент не был найде";

 

}

Создаю контейнер, который будет содержать объекты пользовательского типа

multimap<int, adress> mymap;

multimap<int, adress>::iterator mult_it;

Открываю текстовый файл «container_1» и считываю данные оттуда.

while (getline(schit, adres))

{

for (int i = 0; i < 2; i++)

{

v = adres.find(";", v);

endV[i] = v;

v = v + 1;

}

v = 0;

adress new_add;

new_add.name = adres.substr(0, endV[0]);

new_add.street = adres.substr(endV[0] + 1, endV[1] - endV[0] - 1);

new_add.number = stoi(adres.substr(endV[1] + 1, adres.length()));

mymap.emplace(keycount, new_add);

keycount = keycount + 1;

}

schit.close();

Сортирую элементы в контейнере по убыванию. Просматриваю его содержимое.

sort_u(mymap);

cout << "В котейнере содержатся следующие данные: " << endl;

for (mult_it = mymap.begin(); mult_it!= mymap.end(); mult_it++)

{

cout << mult_it->first << " - " << mult_it->second << endl;

}

cout << endl;

С помощью ранее написанной функции осуществляю поиск элемента в контейнере по условию (адрес с номером дома 5).

adress uslov("a", "b", 5);

Search(mymap, uslov);

cout << endl;

Создаю новый контейнер, в котором будут храниться элементы удовлетворяющие заданному условию (номер дома < 10). Создаю итератор.

list <adress> sp_list;

list<adress>::iterator l_it;

Перемещаю в контейнер все элементы, которые подходят под условие.

for (mult_it = mymap.begin(); mult_it!= mymap.end(); mult_it++)

{

if (mult_it->second.number < 10)

{

sp_list.push_back(mult_it->second);

}

}

Просматриваю содержимое второго контейнера.

for (l_it = sp_list.begin(); l_it!= sp_list.end(); l_it++)

{

cout << *l_it << endl;

}

cout << endl;

Сортирую оба контейнера по возрастанию.

VozrSort(mymap);

sp_list.sort();

Снова просматриваю содержимое контейнеров.

for (mult_it = mymap.begin(); mult_it!= mymap.end(); mult_it++)

{

cout << mult_it->first << " - " << mult_it->second << endl;

}

cout << endl;

 

for (l_it = sp_list.begin(); l_it!= sp_list.end(); l_it++)

{

cout << *l_it << endl;

}

Путем слияния двух первых контейнеров получаю третий.

multimap<int, adress> cont_3 = mymap;

multimap<int, adress>::iterator mult3_it;

int r = 10;

for (l_it = sp_list.begin(); l_it!= sp_list.end(); l_it++)

{

cont_3.emplace(r, *l_it);

r = r + 5;

}

Просматриваю содержимое третьего контейнера.

for (mult3_it = cont_3.begin(); mult3_it!= cont_3.end(); mult3_it++)

{

cout << mult3_it->first << " - " << mult3_it->second << endl;

}

cout << endl;

Подсчитываю и вывожу на экран количество элементов, удовлетворяющих условию (адрес с номером дома 20).

int kolvo = 0;

int usl = 20;

 

for (mult3_it = cont_3.begin(); mult3_it!= cont_3.end(); mult3_it++)

{

if (mult3_it->second.number > usl)

{

kolvo = kolvo + 1;

}

}

cout << "В cont_3 хранится " << kolvo << " элементов с number > " << usl << endl;

Определяю, еслть ли в контейнере элемент удовлетворяющий условию (адрес с номером дома > 70).

for (mult3_it = cont_3.begin(); mult3_it!= cont_3.end(); mult3_it++)

{

if (mult3_it->second.number > 70)

{

flag = true;

break;

}

}

Вывожу ответ на экран.

if (flag)

{

cout << "В контейнере 3 найден элемент, удовлетворяющий условию" << endl;

}

else

{

cout << "В контейнере 3 не найден элемент, удовлетворяющий условию" << endl;

}

ЭКСПЕРИМЕНТАЛЬНАЯ ЧАСТЬ

Программа 1

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

Рисунок 1 - Вывод содержимого контейнера до изменений и после

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

Рисунок 2 - Вывод окончательного содержимого двух контейнеров


 

Программа 2

Программа выводит на экран содержимое первого контейнера. Эти данные программа считывает из текстового файла «container_1.txt».

Рисунок 3 - Данные, содержащиеся в первом контейнере

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

Рисунок 4 - Сообщение об удалении и замене элементов

Программа выводит содержимое контейнера после изменений.

Рисунок 5 - Содержимое контейнера после изменений

 

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

Рисунок 6 - Сообщение об удалении элементов первого контейнера, о добавлении элементов во второй контейнер

 

Программа выводит окончательное содержимое двух контейнеров.

Рисунок 7 - Окончательное содержимое двух контейнеров

 

Программа 3

Программа выводит на экран содержимое первого контейнера. Эти данные программа считывает из текстового файла «container_1.txt».

Рисунок 8 - Начальное содержимое контейнера

 

После поиска элемента по условию (адрес с номером дома 5), программа выводит результат. Далее уведомляет нас о следующем действии, а именно, перемещении всех элементов первого контейнера (multimap) во второй контейнер (list) по условию (адрес с номером дома < 10).

Рисунок 9 - Сообщение о поиске элемента по условию

 

Результатом такого перемещения служит содержимое второго контейнера (list).

Рисунок 10 - Результат перемещения элементов

 

Расположения элементов контейнера multimap и list после сортировки по возрастанию.

Рисунок 11 - Элементы, отсортированные по возрастанию (multimap)

 

Рисунок 12 - Элементы, отсортированные по возрастанию (list)

 

Путем слияния двух контейнеров, получаем третий контейнер. Программа выводит его содержимое.

Рисунок 13 - Содержимое третьего контейнера

 

Производим поиск по условию в третьем контейнере. Первый поиск – количество адресов с номером дома > 20. Второй поиск – «Есть ли в третьем контейнере адрес с номером дома > 70».

Рисунок 14 - Результат поиска по условию

 

ЗАКЛЮЧЕНИЕ

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

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

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

3. Программа 3 демонстрирует использование алгоритмов STL

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

Объектно-ориентированное программирование позволяет разложить проблему на составные части, каждая из которых становится самостоятельным объектом. Каждый из объектов содержит свой собственный код и данные, которые относятся к этому объекту. Поэтому объектно-ориентированное программирование является эффективным решением при разработке крупных программных проектов.

 


 

СПИСОК ИСПОЛЬЗОВАННОЙ ЛИТЕРАТУРЫ

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

2. Галовиц Я., C++17 STL. Стандартная библиотека шаблонов/C++17 STL. Стандартная библиотека шаблонов

3. Лафоре, Р; Объектно-ориентированное программирование в С++ – М.: Питер, 2018. – 928 с.

4. Павловская, Т.А. С/ С++. Программирование на языке высокого уровня / Т.А. Павловская. – СПб.: Питер, 2011. – 461 с.

5. Панюкова, Т. А. Языки и методы программирования. Создание простых GUI-приложений с помощью Visual С++. Учебное пособие / Т.А. Панюкова, А.В. Панюков. - Москва:Мир, 2015. - 144 c.

6. Пахомов, Б. C/C++ и MS Visual C++ 2008 для начинающих / Б. Пахомов. – Издательство: BHV, 2008. – 624 с.

7. Подбельский, В; Курс программирования на языке Си – М.: ДМК Пресс, 2018. – 384 с.

8. Прата, С; Язык программирования C++. Лекции и упражнения. – М.: Вильямс Издательский дом, 2018. – 1248 с.

9. prog-cpp.ru [Электронный ресурс] – Режим доступа: https://prog-cpp.ru/oop/


 

ПРИЛОЖЕНИЯ

Приложение 1

Программа 1

#include <iostream>

#include <string>

#include <map>

 

using namespace std;

 

 

template <typename T>

void show_mmap(const T& Input)

{

for (auto e = Input.cbegin(); e!= Input.cend(); ++e)

{

cout << e->first << " -> " << e->second << endl;

}

cout << endl;

}

 

int main()

{

setlocale(LC_ALL, "Rus");

//создание 1 контейнера

multimap<int, string> mymap;

 

mymap.insert(make_pair(1, "element1"));

mymap.insert(make_pair(2, "element2"));

mymap.insert(make_pair(3, "element3"));

mymap.insert(make_pair(4, "element4"));

 

// просмотр контейнера

show_mmap(mymap);

 

// измененние контейнера()

mymap.insert(make_pair(4, "element44"));//добавлю еще один элемент с ключом 4

cout << "Добавлен новый элемент" << endl;

show_mmap(mymap);

//Удаление элемента

auto NumErase = mymap.erase(4);

cout << "Удалено "<< NumErase << " объекта" << endl;

show_mmap(mymap);

 

//просмотр с итераторами

multimap <int, string>::iterator it = mymap.begin();

cout << "Контейнер 1: " << endl;

for (it; it!= mymap.end(); it++) {

cout << it->first << " - " << it->second << endl;

}

cout << endl;

 

//создание второго контейнера

multimap <int, string> mymap2;

 

mymap2.insert(make_pair(11, "number1"));

mymap2.insert(make_pair(22, "number2"));

mymap2.insert(make_pair(33, "number3"));

mymap2.insert(make_pair(44, "number4"));

 

//Изменить первый контейнер, удалив из него n элементов после заданного и добавив затем

//в него все элементы из второго контейнера

 

int n;

cout << "Количество элементов, которые будут удалены: ";

cin >> n;

it = mymap.begin();

advance(it, n);

mymap.erase(mymap.begin(), it);

mymap.insert(mymap2.begin(),mymap2.end());

 

 

//вывод обоих контейнеров

cout << "Вывод контейнеров" << endl;

cout << "Контейнер 1: " << endl;

show_mmap(mymap);

cout << "Контейнер 2: " << endl;

show_mmap(mymap2);

 

}

Рисунок 15 - Полный вывод Программы 1


 

Приложение 2

Программа 2

#include <iostream>

#include <string>

#include <map>

#include <fstream>

 

using namespace std;

 

class adress {

public:

string name;

string street;

int number;

 

adress() //создаю конструктор без параметров

{

name = ""; street = ""; number = 0;

}

adress(string NAME, string STREET, int NUMBER) //создаю конструктор с параметрами

{

name = NAME; street = STREET; number = NUMBER;

}

 

};

 

istream& operator>> (istream& is, adress& adr)//перегружаю оператор >>

{

is >> adr.name;

is >> adr.street;

is >> adr.number;

return is;

}

 

ostream& operator<<(ostream& os, const adress& adr) { // Перегружаю оператор <<

return os << adr.name << " " << adr.street << " " << adr.number;

}

 

void Zam_el(int number_zamena, adress zn, multimap<int, adress>& mm)

{

mm.find(number_zamena)->second = zn;

}

 

int main()

{

setlocale(LC_ALL, "Rus");

//1.Создать объект-контейнер в соответствии с вариантом задания и заполнить его данными,

//тип которых определяется вариантом задания.

 

multimap<int, adress> mymap;

multimap<int, adress>::iterator it;

 

ifstream schit("container_1.txt");

string adress_2;

int endV[2];

int v = 0, keycount = 1;

 

 

while (getline(schit, adress_2))

{

for (int i = 0; i < 2; i++)

{

v = adress_2.find(";", v);

endV[i] = v;

v = v + 1;

}

v = 0;

adress newAdress;

newAdress.name = adress_2.substr(0, endV[0]);

newAdress.street = adress_2.substr(endV[0] + 1, endV[1] - endV[0] - 1);

newAdress.number = stoi(adress_2.substr(endV[1] + 1, adress_2.length()));

mymap.emplace(keycount, newAdress);

keycount = keycount + 1;

}

schit.close();

 

//2.Просмотреть контейнер.

 

cout << "Данные в контейнере:" << endl;

for (it = mymap.begin(); it!= mymap.end(); it++)

{

cout << it->first << " - " << it->second << endl;

}

cout << endl;

 

//3. Изменить контейнер, удалив из него одни элементы и заменив другие.

 

cout << "Элементы с ключами 3 и 5 были удалены" << endl;

 

mymap.erase(3); mymap.erase(5);

 

cout << "Замена элементов с ключами 2 и 4" << endl;

 

adress ZamAd("Evgeniy(zamena)", "Pokrovsaya", 34);

Zam_el(2, ZamAd, mymap);

adress ZamAd2("Olga(zamena)", "Minina", 15);

Zam_el(4, ZamAd2, mymap);

 

//4. Просмотреть контейнер, используя для доступа к его элементам итераторы.

 

cout << endl;

cout << "Данные в контейнере после изменений:" << endl;

for (it = mymap.begin(); it!= mymap.end(); it++)

{

cout << it->first << " - " << it->second << " " << endl;

}

cout << endl;

 

// 5.Создать второй контейнер этого же класса и заполнить его данными того же типа, что и первый контейнер.

multimap<int, adress> mymap2;

multimap<int, adress>::iterator it2;

 

ifstream schit2("container_2.txt");

v = 0, keycount = 10;

string adres2;

 

 

while (getline(schit2, adres2))

{

for (int i = 0; i < 2; i++)

{

v = adres2.find(";", v);

endV[i] = v;

v = v + 1;

}

v = 0;

adress newAdress;

newAdress.name = adres2.substr(0, endV[0]);

newAdress.street = adres2.substr(endV[0] + 1, endV[1] - endV[0] - 1);

newAdress.number = stoi(adres2.substr(endV[1] + 1, adres2.length()));

mymap2.emplace(keycount, newAdress);

keycount = keycount + 5;

}

schit2.close();

 

//6. Изменить первый контейнер, удалив из него n элементов после заданного и добавив затем в него все элементы из второго контейнера.

 

int numzam = 1;

int schet = 1;

int n = 2;

cout << endl;

cout << "Удаление 2 элементов после " << numzam << "-го в первом контейнере" << endl;

 

for (it = mymap.begin(); it!= mymap.end(); it++)

{

if ((n > 0) && (schet > numzam))

{

it = mymap.erase(it);

--it;

n = n - 1;

}

schet = schet + 1;

}

 

cout << "Добавление всех элементов второго контейнера в первый" << endl;

 

for (it2 = mymap2.begin(); it2!= mymap2.end(); it2++)

{

mymap.insert(*it2);

}

 

//7. Просмотреть первый и второй контейнеры.

 

cout << endl;

cout << "Содержимое первого контейнера: " << endl;

for (it = mymap.begin(); it!= mymap.end(); it++)

{

cout << it->first << " - " << it->second << " " << endl;;

}

cout << endl;

 

cout << "Содержимое второго контейнера: " << endl;

for (it2 = mymap2.begin(); it2!= mymap2.end(); it2++)

{

cout << it2->first << " - " << it2->second << " " << endl;

}

cout << endl;

return 0;

}

Рисунок 16 - Полный вывод Программы 2

Рисунок 17 - Содержимое текстового файла "container_1.txt"

Рисунок 18- Содержимое текстового файла "container_2.txt"


 

Приложение 3

Программа 3

#include <iostream>

#include <string>

#include <map>

#include <fstream>

#include <vector>

#include <algorithm>

#include <list>

 

using namespace std;

 

class adress {

public:

string name;

string street;

int number;

 

adress() //конструктор без параметров

{

name = ""; street = ""; number = 0;

}

adress(string NAME, string STREET, int NUMBER) //конструктор с параметрами

{

name = NAME; street = STREET; number = NUMBER;

}

 

};

 

//Перегрузка оператора "<"

bool operator < (const adress& adr1, const adress& adr2) {

return adr1.number < adr2.number;

}

 

//Перегрузка оператора ввода ">>"

istream& operator>> (istream& is, adress& adr)

{

is >> adr.name;

is >> adr.street;

is >> adr.number;

return is;

}

 

//Перегрузка оператора вывода "<<"

ostream& operator<<(ostream& os, const adress& adr) {

return os << adr.name << " " << adr.street << " " << adr.number;

}

 

bool comp(adress adr1, adress adr2) {

return adr1.number > adr2.number;

}

 

//Сортировка по убыванию

void sort_u(multimap<int, adress>& mumap)

{

vector<int> num_vec;

vector<adress> sort_vec;

vector<adress>::iterator it;

map<int, adress>::iterator mult_it;

int i = 0;

 

for (mult_it = mumap.begin(); mult_it!= mumap.end(); mult_it++)

{

num_vec.push_back(mult_it->first);

sort_vec.push_back(mult_it->second);

}

 

sort(sort_vec.begin(), sort_vec.end(), comp);

 

for (it = sort_vec.begin(); it < sort_vec.end(); it++)

{

mumap.find(num_vec[i])->second = *it;

i = i + 1;

}

 

}

 

void VozrSort(multimap<int, adress>& m_map)

{

vector<int> zn_vec;

vector<adress> sort_vec;

vector<adress>::iterator it;

map<int, adress>::iterator mult_it;

int i = 0;

 

for (mult_it = m_map.begin(); mult_it!= m_map.end(); mult_it++)

{

zn_vec.push_back(mult_it->first);

sort_vec.push_back(mult_it->second);

}

 

sort(sort_vec.begin(), sort_vec.end());

 

for (it = sort_vec.begin(); it < sort_vec.end(); it++)

{

m_map.find(zn_vec[i])->second = *it;

i = i + 1;

}

 

}

 

 

//поиск

void Search(multimap<int, adress> m_map, adress add)

{

vector<adress> vec_1;

vector<adress>::iterator it;

map<int, adress>::iterator mult_it;

int i = 0;

 

for (mult_it = m_map.begin(); mult_it!= m_map.end(); mult_it++)

{

vec_1.push_back(mult_it->second);

}

 

sort(vec_1.begin(), vec_1.end(), comp);

if (binary_search(vec_1.begin(), vec_1.end(), add, comp))

cout << "Элемент был найден";

else

cout << "Элемент не был найде";

 

}

 

int main()

{

//1. Создать контейнер, содержащий объекты пользовательского типа. Тип контейнера выбирается в соответствии с вариантом задания.

setlocale(LC_ALL, "Rus");

 

multimap<int, adress> mymap;

multimap<int, adress>::iterator mult_it;

 

ifstream schit("container_1.txt");

string adres;

int endV[2];

int v = 0, keycount = 1;

 

 

while (getline(schit, adres))

{

for (int i = 0; i < 2; i++)

{

v = adres.find(";", v);

endV[i] = v;

v = v + 1;

}

v = 0;

adress new_add;

new_add.name = adres.substr(0, endV[0]);

new_add.street = adres.substr(endV[0] + 1, endV[1] - endV[0] - 1);

new_add.number = stoi(adres.substr(endV[1] + 1, adres.length()));

mymap.emplace(keycount, new_add);

keycount = keycount + 1;

}

schit.close();

 

//2. Отсортировать его по убыванию элементов.

 

sort_u(mymap);

 

//3. Просмотреть контейнер.

cout << "В котейнере содержатся следующие данные: " << endl;

for (mult_it = mymap.begin(); mult_it!= mymap.end(); mult_it++)

{

cout << mult_it->first << " - " << mult_it->second << endl;

}

cout << endl;

 

//4. Используя подходящий алгоритм, найти в контейнере элемент, удовлетворяющий заданному условию.

 

cout << "Найдем в контейнере адрес с номером дома 5" << endl;

adress uslov("a", "b", 5);

Search(mymap, uslov);

cout << endl;

 

// 5. Переместить элементы, удовлетворяющие заданному условию в другой (предварительно пустой) контейнер. Тип второго контейнера определяется вариантом задания.

 

list <adress> sp_list;

list<adress>::iterator l_it;

cout << "Перемещение всех элементов multimap (number < 10) в контейнер list" << endl;

 

for (mult_it = mymap.begin(); mult_it!= mymap.end(); mult_it++)

{

if (mult_it->second.number < 10)

{

sp_list.push_back(mult_it->second);

}

}

 

//6. Просмотреть второй контейнер.

cout << endl;

cout << "Контейнер list содержит следующие данные:" << endl;

for (l_it = sp_list.begin(); l_it!= sp_list.end(); l_it++)

{

cout << *l_it << endl;

}

cout << endl;

//7. Отсортировать первый и второй контейнеры по возрастанию элементов.

 

//Сортируем контейнер multimap

VozrSort(mymap);

//Сортируем контейнер list

sp_list.sort();

 

//8. Просмотреть их.

 

cout << "Контейнер multimap содержит следующие данные:" << endl;

for (mult_it = mymap.begin(); mult_it!= mymap.end(); mult_it++)

{

cout << mult_it->first << " - " << mult_it->second << endl;

}

cout << endl;

 

cout << "Содержимое контейнера List:" << endl;

for (l_it = sp_list.begin(); l_it!= sp_list.end(); l_it++)

{

cout << *l_it << endl;

}

 

//9. Получить третий контейнер путем слияния первых двух.

multimap<int, adress> cont_3 = mymap;

multimap<int, adress>::iterator mult3_it;

int r = 10;

for (l_it = sp_list.begin(); l_it!= sp_list.end(); l_it++)

{

cont_3.emplace(r, *l_it);

r = r + 5;

}

 

//10. Просмотреть третий контейнер.

cout << endl;

cout << "cont_3 содержит следующие данные:" << endl;

for (mult3_it = cont_3.begin(); mult3_it!= cont_3.end(); mult3_it++)

{

cout << mult3_it->first << " - " << mult3_it->second << endl;

}

cout << endl;

 

//11.Подсчитать, сколько элементов, удовлетворяющих заданному условию, содержит третий контейнер.

int kolvo = 0;

int usl = 20;

 

for (mult3_it = cont_3.begin(); mult3_it!= cont_3.end(); mult3_it++)

{

if (mult3_it->second.number > usl)

{

kolvo = kolvo + 1;

}

}

cout << "В cont_3 хранится " << kolvo << " элементов с number > " << usl << endl;

 

//12.Определить, есть ли в третьем контейнере элемент, удовлетворяющий заданному условию.

cout << endl;

cout << "Определим, есть ли в третьем контейнере элемент с number > 70" << endl;

bool flag = false;

 

for (mult3_it = cont_3.begin(); mult3_it!= cont_3.end(); mult3_it++)

{

if (mult3_it->second.number > 70)

{

flag = true;

break;

}

}

 

if (flag)

{

cout << "В контейнере 3 найден элемент, удовлетворяющий условию" << endl;

}

else

{

cout << "В контейнере 3 не найден элемент, удовлетворяющий условию" << endl;

}

 

 

return 0;

}

Рисунок 19 - Полный вывод Программы 3

Рисунок 20 - Содержимое текстового файла "container_1.txt"



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2022-07-08 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: