Скачать презентацию Строки n С не содержит стандартного типа данных Скачать презентацию Строки n С не содержит стандартного типа данных

Лекция_9_Строки и контейнеры.ppt

  • Количество слайдов: 46

Строки n. С++ не содержит стандартного типа данных «строка» . Он поддерживает массивы char, Строки n. С++ не содержит стандартного типа данных «строка» . Он поддерживает массивы char, завершённые нуль-символом. Заголовочный файл () описывает функции, работающие с такими массивами. n. Работа с такими массивами и функциями эффективна, но небезопасна, т. к. выходы за границы строк не ипроверяются. n. Тип данных string стандартной библиотеки лишён этих недостатков, но может проигрывать в эффективности. n. Для использования класса необходимо подключить к программе заголовочный файл . n. Длина строки в string изменяется динамически по потребности 1

Конструкторы и присваивание строк В классе string определено несколько конструкторов: string(); //создаётся пустой объект Конструкторы и присваивание строк В классе 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* В классе 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 присваивание конкатенация равенство неравенство меньше Операции = + == != < <= n n присваивание конкатенация равенство неравенство меньше или равно > >= [] << >> += больше или равно индексация вывод ввод добавление Для строк типа string не соблюдается соответствие между адресом первого элемента строки и именем. Кроме операции индексации, для доступа к элементу строки определена функция at: string s(“Вася”); cout << s. at(1); // Выведется символ ‘а’ 4

Функции Присваивание части одной строки другой: assign(const string& str); assign(const string& str, size_type pos, Функции Присваивание части одной строки другой: 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 Вставка в одну строку части другой строки: 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 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 <string> #include <iostream> using namespace std; int main (){ string s 1( Пример #include #include using namespace std; int main (){ string s 1("прекрасная королева"), s 2("ле"), s 3("корова"); cout << "s 3= " << s 3. insert(4, s 2) << endl; cout << "s 3= " << s 3. insert(7, "к") << endl; s 1. erase(0, 3); cout << "s 1= " << s 1. erase(12, 2) << endl; cout << "s 1= " << s 1. replace(0, 3, s 3, 4, 2) << endl; } s 3= королева s 3= королевка s 1= красная корова s 1= лесная корова 8

Поиск подстрок size_type find(const string& str, size_type pos = 0) const; size_type find(char c, Поиск подстрок 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 = Пример 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 size() const; // Количество элементов строки size_type length() const; // Количество элементов строки size_type max_size() const; // Максимальная длина строки size_type capacity() const; // Объем памяти, занимаемый строкой bool empty() const; // Истина, если строка пустая 12

Контейнерные классы n. Это классы, предназначенные для хранения структурированных данных (массивов, линейных списков и Контейнерные классы n. Это классы, предназначенные для хранения структурированных данных (массивов, линейных списков и т. д. ). n. Для каждого типа контейнера определены методы для работы с его элементами вне зависимости от типа данных (шаблоны классов). n. STL – стандартная библиотека шаблонов – содержит контейнерные классы, алгоритмы и итераторы. 13

Использование контейнеров позволяет повысить надёжность программ, их переносимость и универсальность, уменьшить сроки разработки. n Использование контейнеров позволяет повысить надёжность программ, их переносимость и универсальность, уменьшить сроки разработки. n Недостатки: снижение быстродействия программ. n 14

Типы контейнеров n n Контейнеры: последовательные и ассоциативные. Последовательные обеспечивают хранение конечного количества однотипных Типы контейнеров 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 STL определяется в 13 заголовочных файлах: algorithm deque functional iterator list map memory numeric queue set stack utility vector 16

Пример #include <fstream> #include <vector> using namespace std; int main(){ ifstream in ( Пример #include #include using namespace std; int main(){ ifstream in ("inpnum. txt"); vector v; // deque, list int x; while ( in >> x ) v. push_back(x); for (vector: : iterator i = v. begin(); i != v. end(); ++i) cout << *i << " "; /*for (int i = 0; i

Поля контейнерных классов value_type size_type iterator const_iterator - Тип элемента контейнера Тип индексов элементов Поля контейнерных классов 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() Методы-итераторы 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 Для того, чтобы можно было реализовать алгоритмы, корректно и эффективно Итераторы 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 миллиарда Методы получения размера контейнера size() Число элементов max_size() Максимальный размер контейнера (порядка 1 миллиарда элементов) empty() Булевская функция, показывающая, пуст ли контейнер 24

Последовательные контейнеры vector deque list Операция Метод vector deque list Вставка в начало Удаление Последовательные контейнеры vector deque list Операция Метод vector deque list Вставка в начало Удаление из начала Вставка в конец Удаление из конца Вставка в произв. Удал. из произв. Произв. доступ push_front pop_front push_back pop_back insert erase [ ], at + + (+) (+) + + + + + 25

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

Примеры конструкторов // Создается вектор из 10 равных единице элементов: vector <int> v 2 Примеры конструкторов // Создается вектор из 10 равных единице элементов: vector v 2 (10, 1); // Создается вектор, равный вектору v 1: vector v 4 (v 1); // Создается вектор из двух элементов, равных первым двум элементам v 1: vector v 3 (v 1. begin(), v 1. begin() + 2); // Создается вектор из 10 объектов класса monstr // (работает конструктор по умолчанию): vector m 1 (10); // Создается вектор из 5 объектов класса monstr с заданным именем (работает конструктор с параметром char*): vector m 2 (5, monstr(“Вася”)); 27

Присваивание, доступ к элементам В шаблоне vector определены операция присваивания и функция копирования assign: Присваивание, доступ к элементам В шаблоне vector определены операция присваивания и функция копирования assign: vector v 1, v 2; // Первым 10 элементам вектора v 1 присваивается 1: v 1. assign(10, 1); // Первым 3 элементам v 2 присваиваются v 1[5], v 1[6], v 1[7]: v 2. assign(v 1. begin() + 5, v 1. begin() + 8); v 1 = v 2; for (int i = 0; i

Методы для изменения, сравнение vector <int> v(2), v 1(3, 9); v. front() = 100; Методы для изменения, сравнение vector v(2), v 1(3, 9); v. front() = 100; v. back() = 100; int m[3] = {3, 4, 5}; v. insert(v. begin(), m, m + 3); // Содержимое v: 3 4 5 100 v 1. insert(v 1. begin() + 1, v. begin() + 2); // Содержимое v 1: 9 3 4 9 9 v. erase(v. begin()); // Содержимое v: 4 5 100 Для векторов определены операции сравнения = =, !=, <, >, <= и >=. Два вектора считаются равными, если равны их размеры и все соответствующие пары 29 элементов.

Пример использования алгоритмов //#include <fstream> <iostream> <vector> <algorithm> using namespace std; class In_10_50{ public: Пример использования алгоритмов //#include using namespace std; class In_10_50{ public: bool operator()(int x) {return x > 10 && x < 50; }}; int main(){ ifstream in ("inpnum"); vector v; int x; while ( in >> x) v. push_back(x); for (int i = 0; i

Функциональные объекты n n n Функциональным объектом называется класс, в котором определена операция вызова Функциональные объекты n n n Функциональным объектом называется класс, в котором определена операция вызова функции Чаще всего эти объекты используются в качестве параметров стандартных алгоритмов для задания пользовательских критериев сравнения объектов или способов их обработки. Функциональные объекты стандартной библиотеки описаны в заголовочном файле . Объекты, возвращающие значения типа bool, называются предикатами. Адаптером функции называют функцию, которая получает в качестве аргумента функцию и конструирует из нее другую функцию. На месте функции может быть также функциональный объект. Стандартная библиотека содержит описание нескольких типов адаптеров: n n связыватели для использования функционального объекта с двумя аргументами как объекта с одним аргументом; отрицатели для инверсии значения предиката; адаптеры указателей на функцию; адаптеры методов для использования методов в алгоритмах. 31

Арифметические функциональные объекты Имя plus Тип Резу ль тат бинарны x + y й Арифметические функциональные объекты Имя 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 бинарны Предикаты Имя Тип Резу ль тат equal_to бинарны x == y й not_equ бинарны x != y al_to й greater бинарны x > y й less бинарны x < y й greater_ бинарны x >= y equal й 33

Пример применения адаптера функции #include <iostream> #include <functional> #include <algorithm> using namespace std; struct Пример применения адаптера функции #include #include #include using namespace std; struct A{ int x, y; }; bool lss(A a 1, A a 2){return a 1. x < a 2. x; } int main(){ A ma[5] = {{2, 4}, {3, 1}, {2, 2}, {1, 2}}; A elem = {3, 0}; cout << count_if(ma, ma + 5, bind 2 nd(ptr_fun(lss), elem)); return 0; } связыватель 34

Пример работы со списком #include <fstream> #include <list> using namespace std; void show (const Пример работы со списком #include #include using namespace std; void show (const char *str, const list &L) { cout << str << ": " << endl; for (list: : const_iterator i = L. begin(); i != L. end(); ++i) cout << *i << " "; cout << endl; } 35

int main(){ list<int> L; list<int>: : iterator i; int x; ifstream in( int main(){ list L; list: : iterator i; int x; ifstream in("inpnum"); while ( in >> x) L. push_back(x); show("Исходный список", L); L. push_front(1); i = L. begin(); L. insert(++i, 2); show("После вставки 1 и 2 в начало", L); Исходный список: 56 34 54 0 76 23 51 11 76 88 После вставки 1 и 2 в начало: 1 2 56 34 54 0 76 23 51 11 76 88 36

После вставки 100 i = L. end(); перед последним: L. insert(--i, 100); show( После вставки 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( L. remove(76); show("После удаления элементов со значением 76", L); L. sort(); show("После сортировки", L); L. unique(); show("После unique", L); list L 1 (L); L. reverse(); show("После reverse", L); } После удаления элементов со значением 76: 2 56 34 54 0 23 51 11 100 После сортировки: 0 2 11 11 23 34 51 51 54 56 100 После unique: 0 2 11 23 34 51 54 56 100 После reverse: 100 56 54 51 34 23 11 2 0 38

priority_queue #include <iostream> #include <vector> #include <functional> #include <queue> using namespace std; int main(){ priority_queue #include #include #include #include using namespace std; int main(){ priority_queue , less > P; int x; P. push(13); P. push(51); P. push(200); P. push(17); while (!P. empty()){ x = P. top(); cout << ” Выбран: " << x; P. pop(); } } Выбран: 200 Выбран: 51 Выбран: 17 Выбран: 13 39

Ассоциативные контейнеры Существует пять типов ассоциативных контейнеров: словари (map), словари с дубликатами (multimap), множества Ассоциативные контейнеры Существует пять типов ассоциативных контейнеров: словари (map), словари с дубликатами (multimap), множества (set), множества с дубликатами (multiset) и битовые множества (bitset). Словари часто называют также ассоциативными массивами или отображениями. Словарь построен на основе пар значений, первое из которых представляет собой ключ для идентификации элемента, а второе — собственно элемент. 40

#include <fstream> #include <iostream> #include <string> #include <map> using namespace std; typedef map <string, #include #include #include #include using namespace std; typedef map > map_sl; int main(){ map_sl m 1; ifstream in("phonebook"); string str; long num; while (in >> num) { in. get(); getline(in, str); m 1[str] = num; cout << str << " " << num << endl; } 41

m 1[ 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 <fstream> #include <iomanip> Пример использования контейнеров Программа формирует указатель для заданного текcтового файла: #include #include #include #include #include using namespace std; typedef set > set_i; typedef map > map_ss; 43

bool wordread(ifstream &in, string &word, int &num){ char ch; for (; ; ){ // 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; 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: : 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