Реферат Курсовая Конспект
Короткі теоретичні відомості - раздел Образование, Навчальної дисципліни Основи програмування та алгоритмічні мови Stl - Це Бібліотека Стандартних Шаблонів. Вона Містить, Напри...
|
STL - це бібліотека стандартних шаблонів. Вона містить, наприклад, що часто зустрічаються способи організації даних - так називані контейнери: динамічні масиви, двонаправленi списки, стеки й ін. Крім того, STL містить безліч алгоритмів що часто зустрічаються: сортування (як на всій безлічі, так і на частині), знаходження мінімального й максимального значень й ін. Кожен такий алгоритм працює з різними типами контейнерів. Ви, наприклад, можете використати той самий алгоритм сортування як для динамічного масиву, так і для стека.
STL складається із трьох основних частин: контейнери, алгоритми й iтератори.
Частина перша. Вона містить різноманітні контейнери. Частина контейнерів зрозуміла і - це динамiчнi масиви, списки, черги й ін. Інша частина більше просунута, якщо можна так виразитися. Сюди, наприклад, ставляться так називані асоціативні контейнери. Основна їхня відмінна риса - це те, що значення, що зберігаються в них, шукаються по ключах. При цьому ключ може бути самим різним. Аналогія такого контейнера з життя - це телефонна книга. Там номера телефонів шукаються на прізвище власника або назви фірми.
У кожному контейнері крім властиво даних є методи для роботи із цими даними (для додавання, пошуку, видалення й ін.).
Друга частина бібліотеки STL - це алгоритми. Алгоритми не є частиною контейнерів, а утворять окрему підсистему. Але при цьому майже будь-який алгоритм може застосовуватися до майже будь-якого контейнеру. Т. е. викликаючи метод для деякого алгоритму, ми викликаємо цей метод сам по собі, а не для екземпляра деякого класу. Контейнер же, до якого застосовується алгоритм, передається як параметр.
І, нарешті, третя частина STL - це різноманітні iтератори. У першому наближенні iтератор - це деякий покажчик, що може оббігати всі елементи контейнера. iтератори грають такі ж ролі, що й індекс в елемента масиву. Через індекс масиву ми можемо одержати деякий елемент масиву, і через iтератор ми можемо одержати деякий елемент контейнера. Iтератори бувають різних типів: для руху тільки вперед, для руху в обидва боки й ін.
Приклад контейнера vector:
Vector є не чим іншим, як динамічним одномірним масивом - тобто ви можете додавати в нього елементи, видаляти їх і т.п.
Ввід приклад використання цього шаблона:
#include <iostream>// Додаємо потрібний простір імен.#include <vector>using namespace std;void main(){ // Повідомляємо вектор із цілих. vector <int> k; // Додаємо елементи в кінець вектора. k.push_back(22); k.push_back(11); k.push_back(4); // Показуємо всі елементи вектора. for (int i = 0; i<k.size(); i++) { cout<<k[i]<<"\n"; } cout<<"***\n"; // Видаляємо елемент із кінця вектора. k.pop_back(); // Показуємо всі елементи вектора. for (i = 0; i<k.size(); i++) { cout<<k[i]<<"\n"; } cout<<"***\n"; // Видаляємо всі елементи вектора k.clear(); // Перевіряємо, що вектор порожній. if(k.empty) { cout<<"Vector is empty\n"; }}Використані методи й змінні шаблона vector (push_back, pop_back, clear й empty) досить ясні з коментарів. Звернете ще увагу, що для доступу до окремих елементiв вектора ми використаємо оператор [] - як і для елементів масиву. Також зверніть увагу, що ми повинні підключити потрібний простір імен (vector).
Виведе цей код, як і слід було сподіватися, спочатку 22, 11 й 4, потім, після видалення останнього елемента вектора, 22 й 11, і потім, після видалення всіх елементів вектора, напис "Vector is empty"
А от ще які класи-контейнери є в STL:
list - двонаправлений список. Доступ до елементів можливий тільки послiдовний із двох сторін списку.
stack - стік.
map - асоціативний список. Зберігає дані у вигляді пари Джерело-Значення (з кожен ключем зв'язане тільки одне значення).
multimap - асоціативний список. Зберігає дані у вигляді пари Джерело-Значення (з кожен ключем зв'язано тільки кілька значень).
set - безліч. Всі його елементи унікальні.
multiset - безліч. У ньому можуть бути співпадаючі елементи.
queue - черга.
deque - двостороння черга.
bitset - набір бiтов (кожний з яких відповідає за відсутність / наявність чого-небудь).
Для використання цих шаблонів ви повинні написати на початку програми потрібний include. Як правило, include пишеться такий же, як ім'я шаблона (так, наприклад, для використання шаблона list треба написати #include ). Два виключення - для використання multimap треба в include додати map і для multiset - set.
Отже: контейнер - шаблон класу, службовець для зберігання даних. Простими словами: контейнер потрібний нам як "обгортка" навколо наших даних, щоб зберігати їх, наприклад, у списку. Такий список можна організувати із чисел float, з рядків string, з об'єктів створеного нами класу (структури), і т.д.
Приклад ітератора:
У першому наближенні iтератор - це покажчик на деякий елемент у контейнері. І, як й у випадку з покажчиками, добратися до елемента контейнера можна через безiменний iтератор.
От приклад коду:
#include <iostream>#include <vector>using namespace std;void main(){ // Повідомляємо вектор із цілих. vector <int> k; // Додаємо елементи в кінець вектора. k.push_back(22); k.push_back(11); k.push_back(4); // Повідомляємо iтератор. vector <int>::iterator p; // Установлюємо iтератор у початок // і пересуваємо його в циклі // на наступну позицію. for (p = k.begin(); p < k.end(); p++) { // Виводимо вміст елементів вектора // через безiменний iтератор. cout<<*p<<"\n"; }}Вихід: 22, 11 й 4.
Iтератор - спеціальний тип, службовець аналогом Си-шного покажчика, використається для проходу за списком, масиву, пошуку елемента в асоціативному списку, і т.д. Це дійсний аналог покажчика, до нього можна застосовувати операції ++ й -- , "зірочку" або -> для одержання значення. Операція ++ зрушує iтератор до наступного елемента динамічного масиву, списку, черги й т.п. Можна порівнювати два iтератора. Замість NULL, ознакою виходу за межі припустимих значень служить спеціальний iтератор, одержаний з контейнера за допомогою функції end().
Приклад алгоритму:
Розглянемо застосування алгоритмів на прикладі сортування елементів вектора.
#include <iostream>#include <vector>#include <algorithm>using namespace std; void main(){ // Повідомляємо вектор із цілих. vector <int> k; // Додаємо елементи в кінець вектора. k.push_back(22); k.push_back(11); k.push_back(4); k.push_back(100); vector <int>::iterator p; // Висновок невідсортованого вектора. for (p = k.begin(); p<k.end(); p++) { cout<<*p<<"\n"; } // Сортування вектора. sort(k.begin(), k.end()); // Висновок відсортованого вектора. cout<<"sorted:\n"; for (p = k.begin(); p<k.end(); p++) { cout<<*p<<"\n"; }}Як ви бачите, головна частина в нашій програмі - це рядок
... // Сортування вектора. sort(k.begin(), k.end()); ...При виклику функції sort ми вказуємо, від якого й до якого елементів ми робимо сортування. У нашому випадку ми сортуємо наш вектор від початку й до кінця.
Результатом виконання програми буде висновок чисел 4, 11, 22, 100 (саме в такому, відсортованому порядку).
Зверніть увагу, що функція sort не належить нашому вектору. Т. е. ми не пишемо щось начебто
... k.sort(...); ...Т. е. наш метод сортування (як й інші алгоритми) утворить окрему підсистему в бібліотеці STL (поряд, наприклад, з контейнерами - тим же вектором, наприклад).
Алгоритм - шаблон функції, що виконує конкретне завдання (пошук, сортування й т.д.) над будь-якими контейнерами. Функція-алгоритм приймає як параметри iтератори або покажчики.
Приклад зберігання об'єктів у списку / динамічному масиві:
#include < list>
#include < vector>
using namespace std;
struct MyStruct
{
int A;
float B;
char C[50];
}
void main()
{
vector < MyStruct> arr;
MyStruct obj;
arr.push_back(obj);
arr[0].A = 123;
list < MyStruct> thelist;
thelist.push_back(obj);
thelist.push_back(obj);
thelist.push_back(obj);
for(list< MyStruct>::iterator i = thelist.begin(); i != thelist.end(); i++)
{
// можна звернутися до структури так:
(*i).A = 123;
// а можна одержати посилання й працювати з нею:
MyStruct &thestruct = *i;
thestruct.B = -0.234;
strcpy(thestruct.C, "Some text");
}
}
приклад організації списка списків, масивів масивів і т.п.
У будь-якому контейнері можна зберігати вкладений контейнер. Для простоти запису, можна використати typedef-и:
#include < list>
#include < vector>
using namespace std;
// відключаємо попередження через занадто довгі імена типів
#pragma warning(disable: 4786)
void main()
{
typedef list< float> ListOfFloat; // список float-ов
typedef list< ListOfFloat> ListOfListOfFloat; // список списків float-ов
// як можна працювати зі списком списків:
ListOfListOfFloat thelist;
// додаємо 2 елементи в список списків:
thelist.resize(2);
// а можна й так:
ListOfFloat thelistinside;
thelistinside.push_back(-0.34f);
thelistinside.push_back(3.45f);
thelist.push_back(thelistinside);
// або от так:
thelist.push_back(ListOfFloat());
// проходимо в циклі по списках - зовнішньому й вкладеному
for(ListOfListOfFloat::iterator i1 = thelist.begin(); i1 != thelist.end(); i1++)
{
// для зручності, одержуємо посилання на вкладений список
ListOfFloat &thelistinside = *i1;
// проходимо по вкладеному списку
for(ListOfFloat::iterator i2 = thelistinside.begin(); i2 != thelistinside.end(); i2++)
{
float value = *i2;
}
}
}
Пояснення:
- створення списку й додавання елементів - за аналогією з vector-ом
- функції resize(), push_front(), clear(), begin() і інших - є в кожному контейнері (в vector-і в тому числі).
- copy(A, B, C) - алгоритм, що копіює всі елементи з контейнера або масиву, на який указує iтератор або покажчик C, у контейнер або масив, на який указують iтераторb або покажчики A й B, причому A указує на перший елемент, B указує на елемент, що перебуває після останнього елемента масиву або контейнера. Для будь-якого контейнера, У можна одержати за допомогою функції end(), для масиву - можна додати розмір масиву до покажчика на перший елемент (наприклад, values + 3).
- итератор ("псевдоуказатель") для кожного контейнера, створюваного нами, має свій відмінний тип. Для того, щоб оголосити iтератор i з контейнера
list< float>,
використається вираження
list< float> ::iterator i.
- як уже говорилося, для одержання значення, на яке вказує iтератор iтератор, використається зірочка: *i. Для переміщення за списком ми просто зрушуємо iтератор операцією ++.
- для того, щоб видалити елемент із "голови" або "хвоста" - використається пара функцій pop_front(), pop_back(). Для видалення довільного елемента використається функція erase(i), де i - це iтератор, що вказує на елемент.
- для вставки елемента в середину списку або масиву використається функція insert(i, v), де v - значення, що вставляє це, i - iтератор, що вказує на елемент, перед яким потрібно вставити значення.
– Конец работы –
Эта тема принадлежит разделу:
ХАРКІВСЬКИЙ НАЦІОНАЛЬНИЙ ЕКОНОМІЧНИЙ УНІВЕРСИТЕТ... Методичні рекомендації до лабораторних робіт з навчальної дисципліни...
Если Вам нужно дополнительный материал на эту тему, или Вы не нашли то, что искали, рекомендуем воспользоваться поиском по нашей базе работ: Короткі теоретичні відомості
Если этот материал оказался полезным ля Вас, Вы можете сохранить его на свою страничку в социальных сетях:
Твитнуть |
Новости и инфо для студентов