Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
pract_oop_03.doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
973.82 Кб
Скачать

Завдання на практичну роботу

1. Використовуючи рекомендовану літературу та дані методичні вказівки, вивчити основні принципи роботи з шаблонними класами.

2. Створити шаблонні класи згідно варіанту (табл. 3.1). Клас повинен містити: конструктор по замовчанню, конструктор з параметрами, конструктор копіювання, деструктор.

3. Оформити звіт (назва і мета роботи, індивідуальне завдання, текст програми, результати роботи програми, висновки).

4. Відповісти на контрольні запитання.

Таблиця 3.1 – Індивідуальні завдання

Завдання

1

2

1

Створити шаблонний клас для виконання операцій з двовимірними векторами: додавання векторів, векторне віднімання, виведення на екран. Конкретний тип для компонентів вектора обрати самостійно.

2

Створити шаблонний клас для виконання операцій з трьохвимірними векторами: додавання векторів, векторне віднімання, виведення на екран. Конкретний тип для компонентів вектора обрати самостійно.

3

Створити шаблоний клас List для роботи із структурою типу "односпрямований список ". Тип елемента списку – довільний, застосувати шаблони. Передбачити функції для виконання таких операцій:

рutinbeg – створити новий елемент списку у його початку;

print – вивести список на екран.

4

Створити шаблоний клас List для роботи із структурою типу "односпрямований список ". Тип елемента списку – довільний, застосувати шаблони. Передбачити функції для виконання таких операцій:

putinend – створити новий елемент списку у його кінці;

print – вивести список на екран.

5

Створити шаблоний клас List для роботи із структурою типу "односпрямований список ". Тип елемента списку – довільний, застосувати шаблони. Передбачити функції для виконання таких операцій:

insert– виконати вставку нового елементу в середину списку;

print – вивести список на екран

Продовження таблиці 3.1

1

2

6

Створити шаблонний клас Lstack – стек, що базується на структурі односпрямованого списку. Тип елементу структури обрати самостійно. Передбачити функції класу для виконання наступних операцій:

рush – занести у стек значення відповідного типу;

pop – добути і вилучити значення із вершини стека;

print – вивести усі значення стека на екран.

7

Створити шаблонний клас Lqueue – черга, що базується на структурі односпрямованого списку. Тип елементу структури обрати самостійно. Передбачити функції класу для виконання наступних операцій:

add – занести у кінець черги задане значення;

del – добути і вилучити значення із початку черги;

print вивести усі значення, що знаходяться у черзі, на екран.

8

Створити шаблонний динамічний клас для роботи з одновимірними масивами. Передбачити функції-компоненти класу для виконання наступних операцій: динамічного присвоєння; поелементного складання та віднімання; консольне введення та виведення масиву.

9

Створити шаблонний динамічний клас для роботи з одновимірними масивами. Передбачити функції-компоненти класу для виконання наступних операцій: об’єднання двох масивів у один (конкатенація); упорядкування масиву по збільшенню та по зменшенню; консольне введення та виведення масиву

10

Створити шаблонний клас для роботи з множинами. Максимальна кількість елементів множини – 65534. Передбачити функції для виконання таких операцій:

include – додати новий елемент у множину;

exclude – вилучити наданий елемент із множини;

print – вивести усі значення із множини на екран;

power – кількість значень множини (потужність).

Продовження таблиці 3.1

1

2

11

Створити шаблонний клас для роботи з множинами. Максимальна кількість елементів множини – 65534. Передбачити функції для виконання таких операцій:

include – додати новий елемент у множину;

exclude – вилучити наданий елемент із множини;

print – вивести усі значення із множини на екран;

union – об’єднання множин.

12

Створити шаблонний клас для роботи з множинами. Максимальна кількість елементів множини – 65534. Передбачити функції для виконання таких операцій:

include – додати новий елемент у множину;

exclude – вилучити наданий елемент із множини;

print – вивести усі значення із множини на екран;

inters – перетин множин

13

Створити динамічний шаблонний клас Stack. Клас повинен вміщувати відповідні функції. Використати розроблений клас для формування інформації про потяг (Train), де кожний елемент містить інформацію про вагон (Carriage): кількість місць, рік виробництва.

14

Створити динамічний шаблонний клас однозв’язний список – List. Клас повинен містити відповідні функції. Використати розроблений клас для формування інформації про маршрут (Route), де кожний елемент зупинка містить наступну інформацію: назва, час прибуття, час відправлення, начальник станції.

15

Створити динамічний шаблонний клас Queue з відповідними функціями. Використати розроблений клас для моделювання конвеєрної лінії виробництва, де кожний елемент деталь містить наступну інформацію: назва, вага, ідентифікаційний номер (id), ідентифікатор гідності.

Контрольні запитання

1. Наведіть поняття шаблонного класу.

2. Які існують правила оголошення шаблонного класу?

3. Чому іноді шаблон класу називають параметризованим типом?

Практична робота №4 Послідовні контейнери vector, list. Асоціативний контейнер map бібліотеки STL

Мета роботи

Навчитись використовувати послідовні контейнери vector, list та асоціативний контейнер map бібліотеки STL при розробці програм.

Основні теоретичні відомості

Стандартна бібліотека шаблонів STL надає три контейнери послідовностей: vector, list та deque. Класи vector та deque це класи на базі масивів. Клас list реалізує двоспрямований список.

В таблиці 4.1 наведені загальні функції для послідовних та асоціативних контейнерів.

Таблиця 4.1 – Загальні функції для послідовних та асоціативних контейнерів

Член-функція

Опис

1

2

Ітератори

begin()

ітератор на перший елемент

end()

ітератор на елемент що знаходиться після останнього

rbegin()

ітератор на останній елемент (для зворотних алгоритмів)

rend()

ітератор на позицію перед першим елементом (для зворотних алгоритмів)

Розмір контейнера

empty()

повертає true, якщо в контейнері немає елементів, інакше false

size()

повертає кількість елементів

max_size()

максимально можливий розмір контейнера

Продовження табл. 4.1

1

2

Видалення елементів

clear()

видалити усі елементи з контейнера

erase (iterator position)

erase (iterator first, iterator last)

видалити елемент за вказаною позицією або елементи з діапазону [first, last)

Інші операціїї над елементами

insert (iterator position)

insert (iterator position, size_type n, const T& x)

вставляє елемент за вказаною позицією або елементи в вказану позицію

swap()

обміняти значення елементів

Перевантажені операції

=

призначити одному контейнеру копії елементів другого

==

визначити чи рівні два контейнери

!=

визначити чи не рівні два контейнери

<

чи менше один контейнер чим інший

>

чи більше один контейнер чим інший

<=

менше або дорівнює один контейнер по відношенню до іншого

>=

більше або дорівнює один контейнер по відношенню до іншого

Один з найбільш популярних контейнерів це vector, що може динамічно змінювати розмір. Клас vector забезпечує структуру даних непереревною областю пам’яті. Це робить можливим ефективний прямий доступ до будь якого елементу контейнера vector за допомогою операції індексування [], як і у звичайних масивах. Класс vector частіше всього використовують, коли дані в контейнері повинні бути відсортировані та легко доступні за допомогою індексу. Контейнер vector підтримує ітератори довільного доступу. Всі алгоритми STL можуть працювати з контейнером vector. Для використання класу підключають файл #include <vector>.

Клас vector описують шаблоном

template < class T, class Allocator = allocator<T> > class vector ;

Клас vector реалізує динамічний масив та має наступні можливості (табл. 4.2).

Другий параметр шаблону, Allocator, вказується рідко. Звичайно використовується значення за замовчуванням. Він був доданий для розв'язку проблеми наявності різних покажчиків як near і far для різних моделей пам'яті.

template <class T>

class vector

{

public:

typedef typename reference;

typedef typename const_reference;

typedef typename iterator;

typedef typename const_iterator;

typedef typename size_type;

typedef typename difference_type;

typedef T value_type;

typedef reverse_iterator<iterator, value_type,

reference, difference_type> reverse_iterator;

typedef const_reverse_iterator<const_iterator,

value_type, reference, difference_type>

const_reverse_iterator;

explicit vector ();

explicit vector (size_type, const T& = T());

vector (const vector<T>&);

template <class InputIterator>

vector (InputIterator, InputIterator);

~vector ();

vector<T>& operator= (const vector<T>&);

template <class InputIterator>

void assign (InputIterator first, InputIterator last);

template <class Size, class T>

void assign (Size n, const T& t = T());

iterator begin ();

const_iterator begin () const;

iterator end ();

const_iterator end () const;

reverse_iterator rbegin ();

const_reverse_iterator rbegin () const;

reverse_iterator rend ();

const_reverse_iterator rend () const;

size_type size () const;

size_type max_size () const;

void resize (size_type,T c = T());

size_type capacity () const;

bool empty () const;

void reserve (size_type);

reference operator[] (size_type);

const_reference operator[] (size_type) const;

reference at (size_type n);

const_reference at (size_type n) const;

reference front ();

const_reference front () const;

reference back ();

const_reference back () const;

void push_back (const T&);

void pop_back ();

iterator insert (iterator, const T& = T());

void insert (iterator, size_type, const T& = T());

template <class InputIterator>

void insert (iterator, InputIterator, InputIterator);

void erase (iterator);

void erase (iterator, iterator);

void swap (vector<T>&);

};

template <class T>

bool operator== (const vector<T>&, const vector <T>&);

template <class T>

bool operator< (const vector<T>&, const vector<T>&);

Таблиця 4.2 – Можливості класу vector

Член-функція

Опис

1

2

Конструктори

vector(const Allocator& alloc = Allocator())

конструктор ініціалізаціїї

vector(size_type n)

створює масив з n елементів зі значеннями по замовчанню

vector(size_type n, const T& value, const Allocator& alloc = Allocator())

створює масив з n елементів зі значеннями value

vector(const vector<T, Allocator>& x)

створює копію іншого вектора

vector(InputIterator first, InputIterator last, const Allocator& alloc = Allocator())

створює вектор розміром last - first, та заповнює значенням елементів з діапазону [first, last)

Призначення елементів

assign(InputIterator first, InputIterator last)

видалити усі елементи та вставити елементи з діапазону [first, last)

assign(size_type, const T& t)

видалити усі елементи та вставити n елементів зі значенням t

Доступ до елементів

at(size_type n)

доступ до елемента з індексом n, при некоректному значенні генерується виключення

back()

доступ к останньому елементу

front()

доступ к першому елементу

Додаткові операції по визначенню розміру вектора

reserve(size_type n)

зарезервувати місце для n елементів

capacity()

повертає кількість елементів, які можна зберігати в векторі

resize (size_type new_size)

перевиділяє поточний розмір вектора

resize (size_type new_size, T value)

перевиділяє поточний розмір вектора; якщо новий розмір більше попереднього, то нові елементи встановлюються в значення value, інакше в значення по замовчанню для типу T

Додавання та видалення елементів

pop_back()

видалити останній елемент

push_back(const T& x)

додати в кінець елемент

Продовження табл.4.2

1

2

Перевантажені операції

[]

операція індексації, не генерує виключення при виході за границі масиву

Приклад 1. В наступній програмі демонструються деякі функцій класу vector. В якості даних класу використовується простий тип int.

#include <iostream>

#include <vector>

using namespace std;

vector<int> arr;

vector<int>::iterator it;

int main(){

// додати в масив 10 елементів зі значенням 8

arr.insert(arr.begin(),10,8);

// вивести кількість елементів в масиві

cout<<"size of arr="<<arr.size()<<endl;

// вивести елементи массиву для перевірки виходу за границі масиву потрібно

// використовувати метод at (визиває виключення),

// а не операцію індексації

cout<<"1. elements of arr: ";

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

cout<<*it<<' ';// виведення елементів з використанням ітератора

cout<<endl;

// в методі at на відмінну від операції []

// відбувається виключення при виході за границі масиву

arr.at(4)=10; // змінюємо 4 елемент

arr.at(5)=11; // змінюємо 5 елемент

cout<<"2. elements of arr: ";

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

cout<<*it<<' ';// виведення елементів з використанням ітератора

cout<<endl;

//видаляємо з 0 по 4 елемент

arr.erase(arr.begin(),arr.begin()+4);

cout<<"3. elements of arr: ";

for(unsigned int i=0;i<arr.size();i++)

cout<<arr[i]<<" ";// звичайне виведення елементів

cout<<endl;

// видалити усі елементи та вивести кількість елементів для перевірки

arr.clear();

cout<<"size of arr="<<arr.size()<<endl;

// добавити в кінець один елемент зі значенням 9

arr.push_back(9);

cout<<"arr[0]="<<arr[0]<<endl;

return 0;

}

Приклад 2. Створити клас для роботи з трьох вимірними векторами. Перевантажити операції введення та виведення, операції “>”, ”==”, ”+”використовувати контейнерни класс vector.

#include <iostream>

#include <vector>

using namespace std;

class vector3d{

int x,y,z;

public:

vector3d() {x=y=z=0;}

vector3d(int a, int b, int c){x=a; y=b; z=c;}

vector3d &operator+(int a);

friend ostream &operator<<(ostream &stream, vector3d obj);

friend bool operator <( vector3d a, vector3d b);

friend bool operator==( vector3d a, vector3d b);

};

vector3d &vector3d::operator+(int a)

{ x+=a; y+=a; z+=a;

return *this; }

ostream &operator <<(ostream &stream, vector3d obj)

{ stream<<obj.x<<" "<<obj.y<<" "<<obj.z<<"\n";

return stream; }

bool operator< (vector3d a, vector3d b)

{return (a.x+a.y+a.z)<(b.x+b.y+b.z); }

bool operator== (vector3d a, vector3d b)

{return (a.x+a.y+a.z)==(b.x+b.y+b.z);}

void main () {

vector<vector3d> v;

unsigned int i;

for (i=0;i<10;i++)

v.push_back(vector3d(i,i+2,i+3));

for (i=0; i<v.size(); i++)

cout<<v[i];

cout<<endl;

for (i=0; i<v.size(); i++)

v[i]=v[i]+10;

for (i=0; i<v.size(); i++)

cout<<v[i];

}

Контейнер послідовності list пропонує ефективну реалізацію вставки й видалення в будь-якім місці контейнера. Якщо більшість вставок і видалень відбувається на кінцях контейнера, більш ефективну реалізацію забезпечить структура даних deque. Шаблон класу list реалізований як двоспрямований список  кожний вузол у списку містить покажчик на попередній вузол списку й покажчик на наступний вузол списку. Це дозволяє шаблону класу list підтримувати двоспрямовані ітератори, що допускають прохід за списком як у прямому, так і у зворотному напрямку. Над списком можна використовувати будь-який алгоритм, що вимагає вхідних, вихідних, послідовних або двоспрямованих ітераторів. Багато з елемент-функцій list маніпулюють елементами контейнера як упорядкованою множиною елементів. Для використання класу підключають файл #include <list>. Клас list описують шаблоном

template <class T> class list;

Клас list реалізує двоспрямований список та має наступні можливості (табл. 4.3).

template <class T>

class list {

public:

typedef typename iterator;

typedef typename const_iterator;

typedef typename reference;

typedef typename const_reference;

typedef typename size_type;

typedef typename difference_type;

typedef T value_type;

typedef reverse_iterator<iterator, value_type,

reference, difference_type> reverse_iterator;

typedef const_reverse_iterator<const_iterator,

value_type, reference,

difference_type> const_reverse_iterator;

explicit list ();

explicit list (size_type n, const T& value = T());

template <class InputIterator>

list (InputIterator first, InputIterator last);

list(const list<T>& x);

~list();

list<T>& operator= (const list<T>&);

template <class InputIterator>

void assign (InputIterator first, InputIterator last);

template <class Size, class T>

void assign (Size n, const T& t = T());

iterator begin ();

const_iterator begin () const;

iterator end ();

const_iterator end () const;

reverse_iterator rbegin ();

const_reverse_iterator rbegin () const;

reverse_iterator rend ();

const_reverse_iterator rend () const;

bool empty () const;

size_type size () const;

size_type max_size () const;

void resize (size_type sz, T c = T());

reference front ();

const_reference front () const;

reference back ();

const_reference back () const;

void push_front (const T& x);

void pop_front ();

void push_back (const T& x);

void pop_back ();

iterator insert (iterator position, const T& x = T());

void insert (iterator position, size_type n, const T& x = T());

template <class InputIterator>

void insert (iterator position, InputIterator first, InputIterator last);

void erase (iterator position);

void erase (iterator position, iterator last);

void swap (list<T>& x);

void splice (iterator position, list<T>& x);

void splice (iterator position, list<T>& x, iterator i);

void splice (iterator position, list<T>& x, iterator first,iterator last);

void remove (const T& value);

template <class Predicate>

void remove_if (Predicate pred);

void unique ();

template <class BinaryPredicate>

void unique (BinaryPredicate binary_pred);

void merge (list<T>& x);

template <class Compare>

void merge (list<T>& x, Compare comp);

void sort ();

template <class Compare>

void sort (Compare comp);

void reverse();

};

template <class T>

bool operator== (const list<T>&, const list<T>&);

template <class T>

bool operator< (const list<T>&, const list<T>&);

Таблиця 4.3 – Можливості класу list

Член-функція

Опис

1

2

Конструктори, деструктор

list ()

конструктор ініціалізаціїї

list (size_type n)

створює список з n елементів зі значеннями по замовчанню

list (size_type n, const T& value)

створює список з n елементів зі значеннями value

list (const list<T>& x)

створює копію іншого списку

~list ()

деструктор

Призначення елементів

assign(InputIterator first, InputIterator last)

видалити усі елементи та вставити елементи з діапазону [first, last)

assign(size_type, const T& t)

видалити усі елементи та вставити n елементів зі значенням t

Доступ до елементів

back()

доступ к останньому елементу

front()

доступ к першому елементу

Додаткові операції по визначенню розміру списку

resize(size_type new_size)

перевиділяє поточний розмір списку

resize(size_type new_siz, T value)

перевиділяє поточний розмір списку; якщо новий розмір більше попереднього, то нові елементи встановлюються в значення value, інакше в значення по замовчанню для типу T

Додавання та видалення елементів

push_front (const T& x)

додати елемент в початок списку

push_back (const T& x)

додати елемент в кінець списку

pop_front ()

видалити першій елемент

pop_back()

видалити останній елемент

remove (const T& value)

видаляє зі списку елемент зі значенням value

unique ()

видаляє зі списку елементи-дублікати

Продовження табл.4.3

1

2

Інші операції над списком

sort ()

сортирує список

reverse ()

змінює порядок елементів списку

merge (list<T>& x)

об’єднує список, що міститься в об’єкті x, зі списком, що викликає функцію; списки перед виклоком данної функції повинні бути відсортировані за допомогою sort ()

splice (iterator position, list<T>& x)

додає в список x список, що виклає дану функцію, в позицію, що вказана ітератором position

splice (iterator position, list<T>& x, iterator i)

видаляє зі списку x елемент, на який вказує ітератор i, і зберігає його в спсику, що викликає функцію, в позиції, на яку вказує ітератор position

splice (iterator position, list<T>& x, iterator first, iterator last)

видаляє зі списку x діапазон, що визначається параметрами [first, last) та зберігає його у списку, що викликає функцію, починаючи з позиції, що вказана ітератором

Приклад 3. В наступній програмі демонструється деякі функцій класу list. В якості даних класу використовується простий тип int.

#include <iostream>

#include <list>

#include <algorithm>

#include <iterator>

using namespace std;

// прототип для шаблону функції printList

template <class T>

void printList(const list<T> &listRef);

int main()

{

const int SIZE=4;

int array[SIZE]={2,4,6,8};

list <int> l1, l2; // створити список для int

// вставити елементи в l1

l1.push_front(1); l1.push_front(2);

l1.push_back(4); l1.push_back(3);

cout<<"l1 contains:"; printList(l1);

l1.sort(); // сортувати значення

cout<<"\nl1 after sorting contains: "; printList(l1);

// вставити в l2 елементи array

l2.insert(l2.begin(), array, array + SIZE );

cout<<"\nAfter insert, l2 contains: "; printList(l2);

// видалити елементи l2 та вставити в кінець l1

l1.splice(l1.end(),l2);

cout<<"\nAfter splice, l1 contains: "; printList(l1);

l1.sort(); // сортувати значення

cout<<"\nAfter sort, l1 contains: "; printList(l1) ;

// вставити в l2 елементи array

l2.insert(l2.begin(), array, array + SIZE);

l2.sort();

cout<<"\nAfter insert, l2 contains: "; printList(l2);

// видалити елементи l2 та вставити в кінець l1, виконуючи сортировку

l1.merge(l2);

cout<<"\nAfter merge: \nl1 contains: "; printList(l1);

cout<<"\nl2 contains: "; printList(l2);

l1.pop_front(); // видалити елемент з початку

l1.pop_back(); // видалити елемент з кінця

cout<<"\nAfter pop_front and pop_back:\nl1 contains: "; printList(l1);

l1.unique(); // видалити дублікати

cout<<"\nAfter unique, l1 contains: "; printList(l1);

// виконати обмін елементами l1 та l2

l1.swap(l2);

cout<<"\nAfter swap: \nl1 contains: "; printList(l1);

cout<<" \nl2 contains: "; printList(l2);

// замінити зміст l1 елементами l2

l1.assign(l2.begin(), l2.end());

cout<<"\nAfter assign, l1 contains: "; printList(l2);

// видалити елементи l2 и вставити l1, виконуючи сортировку

l1.merge(l2);

cout<<"\nAfter merge, l1 contains: "; printList(l1);

l1.remove(4); //видалити усі цифри чотири

cout<<"\nAfter remove(4), l1 contains: "; printList (l1);

cout<<endl;

return 0; }

// визначення шаблону функції printList; для виведення елементів списку

template <class T>

void printList(const list <T> &listRef)

{

if (listRef.empty()) cout<<"List is empty";

else { list <T>::const_iterator p=listRef.begin();

for (; p!=listRef.end(); ++p) cout<<*p<<' '; }

}

Приклад 4. Книжки характеризуються наступною інформацією: назва та автор. Використати клас list бібліотеки STL для зберігання каталогу книжок. Забезпечити операції введення-виведення інформації про книжки, додавання книжки в каталог.

#include <iostream>

#include <string>

#include <list>

using namespace std;

class book

{ char name[30];

char author[20];

public:

book() {strcpy(name,"");strcpy(author,"");}

book(char* name1,char* author1) {strcpy(name,name1);strcpy(author,author1);}

friend book input_book();

friend void show_books(const list<book> &books);

};

book input_book()

{

book tmp;

cout<<"Book name: "; cin>>tmp.name;

cout<<"Author: "; cin>>tmp.author;

return tmp;

}

void show_books(const list<book> &list_books)

{ list <book>::const_iterator p = list_books.begin();

if (p == list_books.end()) { cout << "No books!!!" << endl; return; }

cout<<"Show catalog book"<<endl;

for (; p!= list_books.end(); ++p) {

cout<<"Book name: "<<p->name<<endl;

cout<<"Author: "<<p->author<<endl; }

}

void main()

{ list <book> books;

unsigned int i,n;

cout<<"Input number book"<<endl; cin>>n;

for (i=0;i<n;i++) books.push_back(input_book());

show_books(books);

}

Асоціативні контейнери STL забезпечують прямий доступ для збереження й добування елементів за допомогою ключів (часто називаних ключами пошуку). Чотирма асоціативними контейнерами є multiset, set, multimap і map. Кожний з асоціативних контейнерів підтримує свої ключі в сортованому стані. Ітерація по асоціативному контейнеру проходить його в порядку сортування для даного контейнера. Класи multiset і set передбачають операції для маніпуляції наборами значень, у яких значення є ключами,  не існує окремого значення, асоційованого з кожним ключем. Основною відмінністю між multiset і set є те, що multiset допускає повторювані ключі, у той час як set їх не допускає. Класи multimap і mар передбачають операції для маніпуляції значеннями, асоційованими із ключами (ці значення іноді називають mapped values, зіставленими значеннями). Основна відмінність між multimap і mар полягає в тому, що multimap допускає зберігання повторюваних ключів з їхніми асоційованими значеннями, а mар допускає зберігання тільки унікальних ключів з асоційованими значеннями.

Асоціативний контейнер map (карта) використовується для швидкого збереження й добування ключів з асоційованими значеннями. У map не допускається дублювання ключів, тому з кожним ключем може бути асоційоване єдине значення. Це називають відображенням «один до одного» (однозначним відображенням). Наприклад, компанія, що використовує особисті номери співробітників, такі, як 100, 200 і 300, могла б застосувати карту, що асоціює ці номери з місцевими телефонами  відповідно 4321, 4115 і 5217. У карті потрібно вказати ключ і швидко одержати асоційовані з ним дані. Контейнер map звичайно називають асоціативним масивом. Вказівка ключа в операції індексації [], застосованої до map, знаходить значення, асоційоване в map із цим ключем. Вставки й видалення можуть проводитися в будь-якім місці map.

Для використання класу підключають файл #include <map>. Клас map описують шаблоном.

template < class Key, class T, class Compare = less<Key>,

class Allocator = allocator<pair<const Key,T> > > class map;

Для зберігання пари ключ/значення використовуються stl клас pair.

typedef pair<const Key, T> value_type;

Елементи автоматично сортуються. Елементи класу map мають тільки унікальні значення ключів.

Клас map реалізує асоціативний масив та має наступні можливості (табл. 4.4).

template <class Key, class T, class Compare = less<Key> >

class map {

public:

typedef Key key_type;

typedef pair<const Key, T> value_type;

typedef Compare key_compare;

typedef typename reference;

typedef typename const_reference;

typedef typename iterator;

typedef typename const_iterator;

typedef typename size_type;

typedef typename difference_type;

typedef reverse_iterator<iterator, value_type, reference, difference_type>

reverse_iterator;

typedef reverse_iterator<const_iterator, value_type, const_reference,

difference_type> const_reverse_iterator;

class value_compare:

public binary_function<value_type, value_type, bool>

{

friend class map;

protected :

Compare comp;

value_compare(Compare c) : comp(c) {}

public :

bool operator() (const value_type& x, const value_type& y) const

{ return comp(x.first, y.first); }

};

explicit map (const Compare& comp = Compare());

template <class InputIterator>

map (InputIterator first, InputIterator last,

const Compare& comp = Compare());

map (const map<Key, T, Compare>& x);

~map();

map<Key, Compare>& operator= (const map<Key, T, Compare>& x);

iterator begin();

const_iterator begin() const;

iterator end();

const_iterator end() const;

reverse_iterator rbegin();

const_reverse_iterator rbegin() const;

reverse_iterator rend();

const_reverse_iterator rend() const;

bool empty() const;

size_type size() const;

size_type max_size() const;

T& operator[] (const key_type& x);

const T& operator[] (const key_type& x) const;

pair<iterator, bool> insert (const value_type& x);

iterator insert (iterator position, const value_type& x);

template <class InputIterator>

void insert (InputIterator first, InputIterator last);

void erase (iterator position);

size_type erase (const key_type& x);

void erase (iterator first, iterator last);

void swap (map<Key, Compare>& x);

key_compare key_comp() const;

value_compare value_comp() const;

iterator find (const key_value& x);

const_iterator find (const key_value& x) const;

size_type count (const key_type& x) const;

iterator lower_bound (const key_type& x);

const_iterator lower_bound (const key_type& x) const;

iterator upper_bound (const key_type& x);

const_iterator upper_bound (const key_type& x) const;

pair<iterator, iterator> equal_range (const key_type& x);

pair<const_iterator, const_iterator>

equal_range (const key_type& x) const;

};

template <class Key, class T, class Compare>

bool operator== (const map<Key, T, Compare>& x,

const map<Key, T, Compare>& y);

template <class Key, class T, class Compare>

bool operator< (const map<Key, T, Compare>& x,

const map<Key, T, Compare>& y);

Таблиця 4.4 – Можливості класу map

Член-функція

Опис

Конструктори, деструктор

map (const Compare& comp = Compare());

конструктор ініціалізаціїї

map (iterator first, iterator last, const Compare& comp = Compare());

створює відображення розміром last - first, та заповнює значенням елементів з діапазону [first, last)

map (const map<Key, T, Compare>& x)

створює копію іншого відображення

Робота з ключами

count(key)

число елементів відповідних до зазначеного ключа. Для класу map значення 1 або 0

find(key)

ітератор на перший елемент із зазначеним ключем

lower_bound(key)

ітератор р на перший елемент, чий ключ більше або дорівнює зазначеному ключу

upper_bound(key)

ітератор на перший елемент, чий ключ більше зазначеного ключа

equal_range(key)

діапазон елементів, чий ключ дорівнює зазначеному ключу

[]

операція індексації по ключу

В кожному елементі map зберігається два значення (ключ та дані), то звертання до елементу в map потрібно виконувати таким чином (p – ітератор контейнера):

– (*p).first – для звертання до ключа;

– (*p).second – для звертання до даних.

Приклад 5. Програма для підрахунку кількості слів у тексті та вивідення частоти зустрічі слів у тексті у відсотках. Небхідно створити файл in.txt, в якому міститься текст.

#include <iostream>

#include <string>

#include <map>

#include <fstream>

using namespace std;

int main()

{

map <string,int> words;

ifstream in;

in.open("in.txt");

string word;

while (in>>word)

words[word]++;

ofstream out;

out.open("out.txt");

int count=0;

map <string,int>::iterator p;

out<<"Words count:"<<endl;

for (p =words.begin();p!=words.end();p ++)

{out<<(*p).first<<": "<<(*p).second<<endl;count+=(*p).second;}

out<<"Words %:"<<endl;

for (p=words.begin();p!=words.end();p++)

out<<(*p).first<<": "<<(float)((float)(*p).second/(float)count)*100<<"%"<<endl;

return 0;

}

Приклад 6. Программа створення тлумачного словнику.

#include <iostream>

#include <map>

#include <cstring>

using namespace std;

class word {

char str[20];

public:

word() { strcpy(str, ""); }

word(char *s) { strcpy(str, s); }

char *get() { return str; }

};

// must define less than relative to word objects

bool operator<(word a, word b)

{

return strcmp(a.get(), b.get()) < 0;

}

class meaning {

char str[80];

public:

meaning() { strcpy(str, "");}

meaning(char *s) { strcpy(str, s); }

char *get() { return str; }

};

int main()

{

map<word, meaning> dictionary;

// вставка в відображення об'єкти класів words и meanings

dictionary.insert(pair<word, meaning>(word("house"),

meaning("A place of dwelling.")));

dictionary.insert(pair<word, meaning>(word("keyboard"),

meaning("An input device.")));

dictionary.insert(pair<word, meaning>(word("programming"),

meaning("The act of writing a program.")));

dictionary.insert(pair<word, meaning>(word("STL"),

meaning("Standard Template Library")));

// введення слова та знаходження його значення

char str[80];

cout << "Enter word: ";

cin >> str;

map<word, meaning>::iterator p;

p = dictionary.find(word(str));

if(p != dictionary.end())

cout << "Definition: " << p->second.get();

else

cout << "Word not in dictionary.\n";

return 0;

}

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]