Лекция_9_Строки и контейнеры.ppt
- Количество слайдов: 46
Строки n. С++ не содержит стандартного типа данных «строка» . Он поддерживает массивы char, завершённые нуль-символом. Заголовочный файл
Конструкторы и присваивание строк В классе string определено несколько конструкторов: string(); //создаётся пустой объект string(const char *); /*создаёт объект string на основе строки старого стиля */ string(const char *, int n); /* создаёт объект типа string и записывает туда n символов из строки*/ string(string &); // конструктор копирования string s 1; string s 2(“Вася”); string s 3(s 2); 2
В классе string определены 3 операции присваивания: string& operator=(const string& str); string& operator=(const char* s); string& operator=(char c); s 2 = s 3; s 1 = “Вася”; s 1 = ‘X’; 3
Операции = + == != < <= n n присваивание конкатенация равенство неравенство меньше или равно > >= [] << >> += больше или равно индексация вывод ввод добавление Для строк типа string не соблюдается соответствие между адресом первого элемента строки и именем. Кроме операции индексации, для доступа к элементу строки определена функция at: string s(“Вася”); cout << s. at(1); // Выведется символ ‘а’ 4
Функции Присваивание части одной строки другой: assign(const string& str); assign(const string& str, size_type pos, size_type n); assign(const char* s, size_type n); Добавление части одной строки к другой: append(const string& str); append(const string& str, size_type pos, size_type n); append(const char* s, size_type n); 5
Вставка в одну строку части другой строки: insert(size_type pos 1, const string& str); insert(size_type pos 1, const string& str, size_type pos 2, size_type n); insert(size_type pos, const char* s, size_type n); Удаление части строки: erase(size_type pos = 0, size_type n = npos); Обмен содержимого двух строк: swap(string& s); самое большое положительное число типа size_type 6
Выделение части строки : string substr(size_type pos = 0, size_type n = npos) const; Преобразование string в строки старого стиля: const char* c_str() const; const char* data() const; (data не добавляет в конец строки нуль-символ) Функция copy копирует в массив s n элементов вызывающей строки, начиная с позиции pos. Нуль-символ в результирующий массив не заносится: size_type copy(char* s, size_type n, size_type pos = 0) const; 7
Пример #include
Поиск подстрок size_type find(const string& str, size_type pos = 0) const; size_type find(char c, size_type pos = 0) const; size_type rfind(const string& str, size_type pos = npos) const; size_type rfind(char c, size_type pos = npos) const; size_type find_first_of(const string& str, size_type pos = 0) const; size_type find_first_of(char c, size_type pos = 0) const; size_type find_last_of(const string& str, size_type pos = npos) const; size_type find_last_of(char c, size_type pos = npos) const; size_type find_first_not_of(const string& str, size_type pos = 0) const; size_type find_first_not_of(char c, size_type pos = 0) const; size_type find_last_not_of(const string& str, size_type pos = npos) const; size_type find_last_not_of(char c, size_type pos = npos) const; 9
Пример char Get. Column() { string good. Char = "ABCDEFGH"; char symb; cout << "Введите обозначение колонки: "; while (1) { cin >> symb; if (-1 == good. Char. find(symb)) { cout << "Ошибка. Введите корректный символ: n"; break; } return symb; } } 10
Сравнение частей строк Для сравнения строк целиком применяются перегруженные операции отношения, а если требуется сравнивать части строк, используется функция compare: int compare(const string& str) const; int compare(size_type pos 1, size_type n 1, const string& str, size_type pos 2, size_type n 2) const; Аналогичные формы функций существуют и для сравнения строк типа string со строками старого стиля. 11
Получение характеристик строк size_type size() const; // Количество элементов строки size_type length() const; // Количество элементов строки size_type max_size() const; // Максимальная длина строки size_type capacity() const; // Объем памяти, занимаемый строкой bool empty() const; // Истина, если строка пустая 12
Контейнерные классы n. Это классы, предназначенные для хранения структурированных данных (массивов, линейных списков и т. д. ). n. Для каждого типа контейнера определены методы для работы с его элементами вне зависимости от типа данных (шаблоны классов). n. STL – стандартная библиотека шаблонов – содержит контейнерные классы, алгоритмы и итераторы. 13
Использование контейнеров позволяет повысить надёжность программ, их переносимость и универсальность, уменьшить сроки разработки. n Недостатки: снижение быстродействия программ. n 14
Типы контейнеров n n Контейнеры: последовательные и ассоциативные. Последовательные обеспечивают хранение конечного количества однотипных величин в виде непрерывной последовательности: векторы (vector), двусторонние очереди (deque) и списки (list), а также адаптеры (варианты) контейнеров — стеки (stack), очереди (queue) и очереди с приоритетами (priority_queue). Ассоциативные контейнеры обеспечивают быстрый доступ к данным по ключу. Построены на основе сбалансированных деревьев: словари (map), словари с дубликатами (multimap), множества (set), множества с дубликатами (multiset) и битовые множества (bitset). Программист может создавать собственные контейнерные классы. 15
STL определяется в 13 заголовочных файлах: algorithm deque functional iterator list map memory numeric queue set stack utility vector 16
Пример #include
Поля контейнерных классов value_type size_type iterator const_iterator - Тип элемента контейнера Тип индексов элементов и т. д. Итератор Константный итератор reverse_iterator - Обратный итератор const_reverse_iterator - Константный обратный итератор reference const_reference key_type key_compare - Тип - Ссылка на элемент - Константная ссылка на элемент - Тип ключа (для асс. контейнеров) критерия сравнения (для асс. конт. ) 18
Итераторы Итератор является аналогом указателя на элемент. Он используется для просмотра контейнера. Все, что требуется от итератора — уметь ссылаться на элемент контейнера и реализовывать операцию перехода к его следующему элементу. Константные итераторы используются тогда, когда значения соответствующих элементов контейнера не изменяются. При помощи итераторов можно просматривать контейнеры, не заботясь о фактических типах данных, используемых для доступа к элементам. Для этого в каждом контейнере определено несколько методов: 19
Методы-итераторы 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 Указывают на элемент, следующий за последним, в обратной последовательности 20
Итераторы n n n Для того, чтобы можно было реализовать алгоритмы, корректно и эффективно работающие с данными различной структуры, стандарт определяет не только интерфейс, но и требования ко времени доступа с помощью итераторов. Поскольку итератор является обобщением понятия «указатель» , семантика у них одинаковая, и все функции, принимающие в качестве параметра итераторы, могут также работать и с обычными указателями. В стандартной библиотеке итераторы используются для работы с контейнерными классами, потоками и буферами потоков. В итераторах используются понятия «текущий указываемый элемент» и «указать на следующий элемент» . Доступ к текущему элементу последовательности выполняется аналогично указателям с помощью операций * и ->. Переход к следующему элементу — с помощью операции инкремента ++. Для всех итераторов определены также присваивание, проверка на равенство и неравенство. 21
Итераторы В соответствии с набором обеспечиваемых операций итераторы делятся на пять категорий. Операции обеспечиваются за постоянное время. Категория итератора Допустимые операции Контейнеры входной (input) x = *i все выходной (output) *i = x все прямой (forward) x = *i, *i = x все двунаправленный (bidirectional) x = *i, *i = x, --i, i-- все произвольного доступа (random access) x = *i, *i = x, --i, i-i + n, i – n, i += n, i -= n i < j, i > j, i <= j, i >= j все, кроме list 22
Итераторы Итератор может быть действительным (когда он указывает на какой-либо элемент) или недействительным. Итератор может стать недействительным в следующих случаях: n итератор не был инициализирован; n контейнер, с которым он связан, изменил размеры или уничтожен; n итератор указывает на конец последовательности. Конец последовательности представляется как указатель на элемент, следующий за последним элементом последовательности. Этот указатель всегда существует. 23
Методы получения размера контейнера size() Число элементов max_size() Максимальный размер контейнера (порядка 1 миллиарда элементов) empty() Булевская функция, показывающая, пуст ли контейнер 24
Последовательные контейнеры vector deque list Операция Метод vector deque list Вставка в начало Удаление из начала Вставка в конец Удаление из конца Вставка в произв. Удал. из произв. Произв. доступ push_front pop_front push_back pop_back insert erase [ ], at + + (+) (+) + + + + + 25
n n n Вектор — структура, эффективно реализующая произвольный доступ к элементам, добавление в конец и удаление из конца. Двусторонняя очередь эффективно реализует произвольный доступ к элементам, добавление в оба конца и удаление из обоих концов. Список эффективно реализует вставку и удаление элементов в произвольное место, но не имеет произвольного доступа к своим элементам. 26
Примеры конструкторов // Создается вектор из 10 равных единице элементов: vector
Присваивание, доступ к элементам В шаблоне vector определены операция присваивания и функция копирования assign: vector
Методы для изменения, сравнение vector
Пример использования алгоритмов //#include
Функциональные объекты n n n Функциональным объектом называется класс, в котором определена операция вызова функции Чаще всего эти объекты используются в качестве параметров стандартных алгоритмов для задания пользовательских критериев сравнения объектов или способов их обработки. Функциональные объекты стандартной библиотеки описаны в заголовочном файле
Арифметические функциональные объекты Имя plus Тип Резу ль тат бинарны x + y й minus бинарны x – y й multi бинарны x * y pli й es divide бинарны x / y s й modul бинарны x % y us й 32
Предикаты Имя Тип Резу ль тат equal_to бинарны x == y й not_equ бинарны x != y al_to й greater бинарны x > y й less бинарны x < y й greater_ бинарны x >= y equal й 33
Пример применения адаптера функции #include
Пример работы со списком #include using namespace std; void show (const char *str, const list
int main(){ list
После вставки 100 i = L. end(); перед последним: L. insert(--i, 100); show("После вставки 100 перед 1 2 56 34 54 0 76 последним", L); 23 51 11 76 i = L. begin(); x = *i; 100 88 L. pop_front(); cout << "Удалили из начала" << x Удалили из начала << endl; 1 i = L. end(); x = *--i; Удалили из конца L. pop_back(); cout << "Удалили из конца" << x 88 << endl; Список после show("Список после удаления", удаления: L); 2 56 34 54 0 76 23 37 51 11 76 100
L. remove(76); show("После удаления элементов со значением 76", L); L. sort(); show("После сортировки", L); L. unique(); show("После unique", L); list
priority_queue #include
Ассоциативные контейнеры Существует пять типов ассоциативных контейнеров: словари (map), словари с дубликатами (multimap), множества (set), множества с дубликатами (multiset) и битовые множества (bitset). Словари часто называют также ассоциативными массивами или отображениями. Словарь построен на основе пар значений, первое из которых представляет собой ключ для идентификации элемента, а второе — собственно элемент. 40
#include
m 1["Petya P. "] = 2134622; // Дополнение словаря map_sl : : iterator i; cout << "m 1: " << endl; // Вывод словаря for (i = m 1. begin(); i != m 1. end(); i++) cout << (*i). first << " " << (*i). second << endl; i = m 1. begin(); i++; cout << “Второй элемент: “; cout << (*i). first << " " << (*i). second << endl; // Вывод элемента по ключу: cout << “Vasia: ” << m 1[“Vasia”] << endl; getline(cin, str); if (m 1. find(str) != m 1. end()) cout << m 1 [str]; else{ cout << (*m 1. upper_bound(str)). first << " " ; cout << (*m 1. lower_bound(str)). first; return 0; } 42
Пример использования контейнеров Программа формирует указатель для заданного текcтового файла: #include
bool wordread(ifstream &in, string &word, int &num){ char ch; for (; ; ){ // Пропуск до первой буквы: in. get(ch); if (in. fail()) return false; if (isalpha(ch) || ch == '_') break; if (ch == 'n') num++; } word = ""; do{ // Поиск конца слова: word += tolower(ch); in. get(ch); }while (!in. fail() && (isalpha(ch) || ch == '_')); if (in. fail()) return false; in. putback(ch); // Если символ - 'n' return true; } 44
int main(){ map_ss m; map_ss: : iterator im; set_i: : iterator is, isbegin, isend; string word; int num = 1; ifstream in ("some_file"); while (wordread(in, word, num)){ im = m. find(word); if (im == m. end()) im = m. insert(map_ss: : value_type(word, set_i())). first; (*im). second. insert(num); } 45
for (im = m. begin(); im != m. end(); im++){ cout << setiosflags(ios: : left) << setw(15) << (*im). first. c_str(); isbegin = (*im). second. begin(); isend = (*im). second. end(); for (is = isbegin; is != isend; is++) cout << " " << *is; cout << endl; } return 0; } 46


