Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
OOP_LAB_Part_2_Obyektno-orientov_progr.DOC
Скачиваний:
11
Добавлен:
03.05.2019
Размер:
418.3 Кб
Скачать

3.Класи-контейнери.

У STL визначені два типи контейнерів – послідовності й асоціативні контейнери.

Ключова ідея для стандартних контейнерів полягає в тім, що коли це представляється розумним, вони повинні бути логічно взаємозамінними. Користувач може вибирати між ними, ґрунтуючись на розуміннях ефективності і потреби в спеціалізованих операціях. Наприклад, якщо часто потрібен пошук по ключі. можна скористатися map (асоціативним масивом). З іншого боку, якщо переважають операції, характерні для списків, можна скористатися контейнером list. Якщо додавання і видалення елементів часто виконується в кінці контейнера, варто подумати про використання черги queue, черги з двома кінцями deque, стека stack. За замовчуванням користувач повинний використовувати vector; він реалізований, щоб добре працювати для самого широкого діапазону задач.

Ідея звертання з різними видами контейнерів – і, у загальному випадку, із усіма видами джерел інформації – уніфікованим способом, веде до поняття узагальненого програмування. Для підтримки цієї ідеї STL містить множину узагальнених алгоритмів. Такі алгоритми рятують програміста від необхідності знати подробиці окремих контейнерів.

У STL визначені наступні класи-контейнери(у кутових дужках зазначені заголовні файли, де визначені ці класи):

bitset множину бітів <bitset.h>

vector динамічний масив <vector.h>

list лінійний список <list.h>

deque двостороння черга <deque.h>

stack стек <stack.h>

queue черга <queue.h>

priority_queue черга з пріоритетом <queue.h>

map асоціативний список для збереження пар ключ/значення, де з кожним ключем зв'язане одне значення <map.h>

multimap з кожним ключем зв'язано два чи більше значення <map.h>

set множина <set.h>

multiset множина, у якій кожен елемент не обов'язково унікальний <set.h>

Огляд операцій

Типи

value_type тип елемента

allocator_type тип розподільника пам'яті

size_type тип індексів, лічильника елементів і т.д.

iterator поводиться як value_type*

reverse_iterator переглядає контейнер у зворотному порядку

reference поводиться як value_type&

key_type тип ключа (тільки для асоціативних контейнерів)

key_compare тип критерію порівняння (тільки для асоціативних контейнерів)

mapped_type тип відображеного значення

Ітератори

begin() вказує на перший елемент

end() вказує на елемент, що випливає за останнім

rbegin() вказує на перший елемент у зворотній послідовності

rend() вказує на елемент, що випливає за останнім у зворотній послідовності

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

front() посилання на перший елемент

back() посилання на останній елемент

operator[](i) доступ за індексом без перевірки

at(i) доступ за індексом з перевіркою

Включення елементів

insert(p,x) додавання х перед елементом, на який вказує р

insert(p,n,x) додавання n копій х перед р

insert(p,first,last) додавання елементів з [first:last] перед р

push_back(x) додавання х в кінець

push_front(x) додавання нового першого елемента (тільки для списків і черг із двома кінцями)

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

pop_back() видалення останнього елемента

pop_front() видалення першого елемента (тільки для списків і черг із двома кінцями)

erase(p) видалення елемента в позиції р

erase(first,last) видалення елементів з [first:last]

clear() видалення всіх елементів

Інші операції

size() число елементів

empty() контейнер порожній?

capacity() пам'ять, виділена під вектор (тільки для векторів)

reserve(n) виділяє пам'ять для контейнера під n елементів

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

swap(x) обмін місцями двох контейнерів

==, !=, < операції порівняння

Операції присвоювання

operator=(x) контейнеру привласнюються елементи контейнера х

assign(n,x) присвоювання контейнеру n копій елементів х (не для асоціативних контейнерів)

assign(first,last) присвоювання елементів з діапазону [first:last]

Асоціативні операції

operator[](k) доступ до елемента з ключем k

find(k) знаходить елемент із ключем k

lower_bound(k) знаходить перший елемент із ключем k

upper_bound(k) знаходить перший елемент із ключем великим k equal_range(k) знаходить lower_bound (нижню границю) і upper_bound (верхню границю) елементів із ключем k

Контейнери vector - вектор.

Вектор vector у STL визначений як динамічний масив з доступом до його елементів по індексі.

template<class T,class Allocator=allocator<T>>class std::vector{…};

де T – тип призначених для збереження даних.

Allocator задає розподільник пам'яті, що за замовчуванням є стандартним.

У класі vector визначені наступні конструктори.

explicit vector(const Allocator& a=Allocator());

explicit vector(size_type число, const T&значення= T(), const Allocator&a= Allocator());

vector(const vector<T,Allocator>&об'єкт);

template<class InIter>vector(InIter початок, InIter кінець, const Allocator&a= Allocator());

Перша форма являє собою конструктор порожнього вектора.

В другій формі конструктора вектора число елементів – це число, а кожен елемент дорівнює значенню значення. Параметр значення може бути значенням за замовчуванням.

Третя форма конструктора вектор – це конструктор копіювання.

Четверта форма – це конструктор вектора, що містить діапазон елементів, заданий ітераторами початок і кінець.

Приклад 1.

vector<int> a;

vector<double> x(5);

vector<char> c(5,’*’);

vector<int> b(a); //b=a

Для будь-якого об'єкта, що буде зберігатися у векторі, повинний бути визначений конструктор за замовчуванням. Крім того, для об'єкта повинні бути визначені оператори < і ==.

Для класу вектор визначені наступні оператори порівняння

==, <, <=, !=, >, >=.

Крім цього, для класу vector визначається оператор індексу [].

  • Нові елементи можуть включатися за допомогою функцій

insert(), push_back(), resize(), assign().

  • Існуючі елементи можуть віддалятися за допомогою функцій

erase(), pop_back(), resize(), clear().

  • Доступ до окремих елементів здійснюється за допомогою ітераторів

begin(), end(), rbegin(), rend(),

  • Маніпулювання контейнером, сортування, пошук у ньому, тощо, можливо за допомогою глобальних функцій файлу-заголовка <algorithm.h>.

Приклад 2.

#include<iostream.h>

#include<vector.h>

using namespace std;

void main()

{vector<int> v;

int i;

for(i=0;i<10;i++)v.push_back(i);

cout<<“size=”<<v.size()<<“\n”;

for(i=0;i<10;i++)cout<<v[i]<<“ ”;

cout<<endl;

for(i=0;i<10;i++)v[i]=v[i]+v[i];

for(i=0;i<v.size();i++)cout<<v[i]<<“ ”;

cout<<endl;

}

Приклад 3. Доступ до вектора через ітератор.

#include<iostream.h>

#include<vector.h>

using namespace std;

void main()

{vector<int> v;

int i;

for(i=0;i<10;i++)v.push_back(i);

cout<<“size=”<<v.size()<<“\n”;

vector<int>::iterator p=v.begin();

while(p!=v.end())

{cout<<*p<<” “;p++;}

}

Приклад 4. Вставка і видалення елементів

#include<iostream.h>

#include<vector.h>

using namespace std;

void main()

{vector<int> v(5,1);

int i;

//вивід

for(i=0;i<5;i++)cout<<v[i]<<“ ”;

cout<<endl;

vector<int>::iterator p=v.begin();

p+=2;

//вставити 10 елементів зі значенням 9

v.insert(p,10,9);

//вивід

p=v.begin();

while(p!=v.end())

{cout<<*p<<” “;p++;}

//видалити вставлені елементи

p=v.begin();

p+=2;

v.erase(p,p+10);

//вивід

p=v.begin();

while(p!=v.end())

{cout<<*p<<” “;p++;}

}

Приклад 5. Вектор містить об'єкти класу користувача.

#include<iostream.h>

#include<vector.h>

#include”student.h”

using namespace std;

void main()

{vector<STUDENT> v(3);

int i;

v[0]=STUDENT(“Іванов”,45.9);

v[1]=STUDENT(“Петров”,30.4);

v[0]=STUDENT(“Сідоров”,55.6);

//вивід

for(i=0;i<3;i++)cout<<v[i]<<“ ”;

cout<<endl;

}

Асоціативні контейнери (масиви)

Асоціативний масив містить пари значень. Знаючи одне значення, що називається ключем (key), ми можемо одержати доступ до іншого, oj yfpbdf’nmcz відображеним значенням (mapped value).

Асоціативний масив можна представити як масив, для якого індекс не обов'язково повинний мати цілочисельний тип:

V& operator[](const K&) повертає посилання на V, що відповідає K.

Асоціативні контейнери – це узагальнення поняття асоціативного масиву.

Асоціативний контейнер map - це послідовність пар (ключ, значення), що забезпечує швидке одержання значення за ключем. Контейнер map надає двонаправлені ітератори.

Асоціативний контейнер map вимагає, щоб для типів ключа існувала операція “<”. Він зберігає свої елементи відсортованими за ключем так, що перебір відбувається один по одному.

Специфікація шаблона для класу map:

template<class Key,class,class Comp=less<Key>,class Allocator=allocator<pair> >

class std::map

У класі map визначені наступні конструктори:

explicit map(const Comp& c=Comp(),const Allocator& a=Allocator());

map(const map<Key,T,Comp,Allocator>& ob);

template<class InIter> map(InIter first,InIter last,const Comp& c=Comp(),const Allocator& a=Allocator());

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

Визначено операцію присвоювання:

map& operator=(const map&);

Визначено наступні операції: ==, <, <=, !=, >, >=.

У map зберігаються пари ключ/значення у виді об'єктів типу pair.

Створювати пари ключ/значення можна не тільки за допомогою конструкторів класу pair, але і за допомогою функції make_pair, що створює об'єкти типу pair, використовуючи типи даних як параметри.

Типова операція для асоціативного контейнера – це асоціативний пошук за допомогою операції індексації([]).

mapped_type& operator[](const key_type& K);

Множини set можна розглядати як асоціативні масиви, у яких значення не грають ролі, так що ми відслідковуємо тільки ключі.

template<class,class Cmp=less<T>,class Allocator=allocator<T>>class std::set{...};

Множину, як і асоціативний масив, вимагає, щоб для типу T існувала операція “менше” (<). Воно зберігає свої елементи відсортованими, так що перебір відбувається один по одному.

Алгоритми

Кожен алгоритм виражається шаблоном функції чи набором шаблонів функцій. Таким чином, алгоритм може працювати з дуже різними контейнерами, що містять значення різноманітних типів. Алгоритми, що повертають ітератор, як правило, для повідомлення про невдачу використовують кінець вхідної послідовності. Алгоритми не виконують перевірки діапазону на їх вході і виході. Коли алгоритм повертає ітератор, це буде ітератор того ж типу, що і був на вході. Алгоритми в STL реалізують більшість розповсюджених універсальних операцій з контейнерами, такі як перегляд, сортування, пошук, вставку і видалення елементів.

Алгоритми визначені в заголовному файлі <algorithm.h>.

Нижче приведені імена деяких найбільше часто користуємих функцій-алгоритмів STL.

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