
- •«Объектно-ориентированный анализ и проектирование»
- •1. Принципы ооп. Классы.
- •Описание классов.
- •Объекты класса.
- •Конструкторы
- •Конструктор копирования
- •Статические элементы класса
- •Дружественные функции и классы
- •Деструкторы
- •Перегрузка операций
- •Перегрузка унарных операций
- •Перегрузка бинарных операций
- •Перегрузка операции присваивания
- •Рекомендации по составу классов
- •2. Наследование
- •Ключи доступа
- •Простое наследование
- •Пример замещения функций (практикум)
- •Виртуальные методы
- •Множественное наследование
- •3. Отношения между классами. Диаграммы класссов на языке uml.
- •4. Шаблоны классов.
- •4.1. Определения шаблонов классов Queue и QueueItem
- •4.2. Конкретизация шаблона класса
- •4.3. Аргументы шаблона для параметров-констант
- •4.4. Функции-члены шаблонов классов
- •5. Обработка исключительных ситуаций
- •5.1. Общий механизм обработки исключений.
- •5.2 . Синтаксис исключений
- •5.3. Перехват исключений
- •5.4. Исключения в конструкторах и деструкторах
- •Vector(int n) // Конструктор
- •5.5. Список исключений функции.
- •6. Строки
- •Преобразование строк
- •7. Контейнерные классы
- •7.1. Векторы.
- •7.2. Двухсторонние очереди (deque).
- •7.3. Списки (List).
- •7.4. Стеки
- •7.5. Очереди (queue)
- •7.6. Очередь с приоритетами(priority_queue)
- •8. Ассоциативные контейнеры
- •8.1. Словари (map)
- •8.2. Словари с дубликатами (multimap)
- •8.3. Множества (set)
- •8.4. Множества с дубликатами (multiset)
- •8.5. Битовые множества (bitset)
8.1. Словари (map)
В словаре (mар) все ключи (первые элементы пар) должны быть уникальны. Элементы в словаре хранятся в отсортированном виде, поэтому для ключей должно быть определено отношение «меньше». Шаблон словаря содержит три параметра: тип ключа, тип элемента и тип функционального объекта, определяющего отношение «меньше»:
template<class Key, class T, class Compare = less<Key> >
class map {
public:
typedef pair<const Key, T> value_type;
explicit map(const Compare& comp = Compare());
template<class lnputlter> map(InputIter first, InputIter last, const Compare& comp = Compare());
map(const map<Key, T, Compare>& x);
…
};
Таким образом, тип элементов словаря value_type определяется как пара элементов типа Key и Т.
Первый конструктор создает пустой словарь, используя указанный функциональный объект. Второй конструктор создает словарь и записывает в него элементы, определяемые диапазоном указанных итераторов. Время работы этого конструктора пропорционально количеству записываемых элементов, если они упорядочены, и квадрату количества элементов, если нет. Третий конструктор является конструктором копирования.
Как и для всех контейнеров, для словаря определены деструктор, операция присваивания и операции отношения. Для доступа к элементам по ключу определена операция []: Т& operator[](const Key &х);
С помощью этой операции можно не только получать значения элементов, но и добавлять в словарь новые.
#include <iostream>
#include <fstream>
#include <string>
#include <map>
using namespace std;
typedef map<string, long, less<string>> map_sl;
int main() {
map_sl m1;
ifstream in("phonebook.txt");
string str;
long num;
while(!in.eof()) {
in >> num;
in.get();
getline(in, str);
m1[str] = num;
cout << str << ' ' << num << '\n';
}
m1["Petya P."] = 2134622;
map_sl :: iterator i;
cout << "m1:" << '\n';
for(i = m1.begin(); i != m1.end(); ++i)
cout << (*i).first << ' ' << (*i).second << '\n';
i = m1.begin(); i++;
cout << "The second element: ";
cout << i->first << ' ' << (*i).second << '\n';
cout << "Vasia: " << m1["Vasia"] << '\n';
// вставка позже
getline(cin, str);
if(m1.find(str) != m1.end())
cout << m1[str];
else {
cout << (*m1.upper_bound(str)).first << ' ';
cout << (*m1.lower_bound(str)).first << ' ';
}
cout << '\n';
// вставка еще позже
map_sl m2;
m2.insert(map_sl::value_type("Lena", 3157725));
str = "Anna";
num = 5536390;
m2.insert(make_pair(str, num));
num = 5172549;
m2.insert(make_pair(str, num));
i = m1.begin();
m2.insert(*i);
m2["Lena"] = 5555555;
for(i = m2.begin(); i != m2.end(); i++)
cout << i->first << ' ' << i->second << '\n';
return 0;
}
Для итераторов словаря допустимы операции инкремента и декремента, но не операции + и -. Ниже приведен результат работы программы (обратите внимание, что словарь выводится в упорядоченном виде):
Petya К. 1001002
Ivanova N.M. 3563398
Vovochka 1180316
Vasia 2334476
ml:
Ivanova N.M. 3563398
Petya K. 1001002
Petya P. 2134622
Vasia 2334476
Vovochka 1180316
The second element: Petya К. 1001002
Vasia: 2334476
Для поиска элементов в словаре определены следующие функции:
iterator find(const key_type &x); //возвращает итератор на найденный элемент в случае успешного поиска или end() в противном случае.
const_iterator find(const key_type& x) const;
iterator lower_bound(const key_type& x); //возвращает итератор на первый элемент, ключ которого больше x, или end(), если такого нет
const_iterator lower_bound(const key_type& x) const;
iterator upper_bound(const key_type& x); //возвращает итератор на первый элемент, ключ которого не меньше х, или end(), если такого нет (если элемент с ключом х есть в словаре, будет возвращен итератор на него).
const_iterator upper_bound(const key_type &x) const;
size_t count(const key_type& x) const;// возвращает количество элементов, ключ которых равен х (таких элементов может быть 0 или 1).
Для вставки и удаления элементов определены функции:
pair<iterator, bool> insert(const value_type& x);
iterator insert(iterator position, const value_type& x);
template<class InputIter> void insert(InputIter first, InputIter last);
void erase(iterator position);
size_t erase(const key_type& x);
void erase(iterator first, iterator last);
void clear();
Первая форма функции используется для вставки в словарь пары «ключ—значение». Функция возвращает пару, состоящую из итератора, указывающего на вставленное значение, и булевого признака результата операции: true, если записи с таким ключом в словаре не было (только в этом случае происходит добавление), и false в противном случае (итератор указывает на существующую запись). Время работы функции пропорционально логарифму количества элементов в словаре.
Таким образом, скорректировать существующую запись, используя функцию вставки, нельзя. Это делается с помощью операции доступа по индексу.
Вторая форма функции insert применяется для ускорения процесса вставки. С этой целью ей передается первым параметром позиция словаря, начиная с которой требуется осуществлять поиск места вставки. Вставка выполняется только в случае отсутствия значения х в словаре. Функция возвращает итератор на элемент словаря с ключом, содержащимся в х.
Например, если известно, что элементы будут помещаться в словарь в порядке возрастания, можно передавать первым параметром в функцию вставки позицию предыдущего элемента (в этом случае время вставки является константой):
#include <iostream>
#include <string>
#include <map>
using namespace std;
typedef map<string, long, less<string> > map_sl;
typedef pair<string, long> pair_sl;
int main(){
pair_sl pi[3] = {pair_sl("Anna", 2234567), pair_sl("Maria", 1234567), pair_sl("John", 3345779)};
map_sl m1;
map_sl :: iterator i = m1.begin();
for(int k = 0; k < 3; k++)
i = m1.insert(i, pi[k]);
for(i = m1.begin(); i != m1.end(); i++)
cout << (*i).first << ' ' << i->second << \n';
// позже
pair <map_sl :: iterator, map_sl :: iterator> p;
p = m1.equal_range("John");
cout << (p.first)->first << ' ' << (p.second)->first << '\n';
return 0;
}
Третья форма функции insert используется для вставки группы элементов, определяемой диапазоном итераторов. Функции удаления элементов и очистки словаря аналогичны одноименным функциям других контейнеров: первая форма функции erase удаляет элемент словаря из позиции, заданной итератором, вторая - по заданному ключу, а третья удаляет диапазон элементов.
Операции вставки в словарь не приводят к порче связанных с ними итераторов и ссылок, а операции удаления делают недействительными только итераторы и ссылки, связанные с удаляемыми элементами.
Для обмена всех элементов двух словарей применяется функция swap:
template <class Key, class Т, class Compare> void swap(map<Key, T, Compare>& x, map<Key, T, Compare>& y);
Функция equal_range возвращает пару итераторов (lowerbound(x), upperbound(x)) для переданного ей значения х:
pair<iterator,iterator> equal_range(const key_type& x);
pair<const_iterator, const_iterator> equal_range(const key_type& x) const;
После вызова функции оба итератора будут указывать на элемент с заданным ключом, если он присутствует в словаре, или на первый элемент, больший него, в противном случае.
// алфавит
#include <iostream>
#include <map>
using namespace std;
int main() {
map<char, int> m;
int i;
for(i = 0; i < 10; i++)
/* Один из вариантов добавления пары
m.insert(pair<char,int>('A'+i,i));*/
m.insert(make_pair((char)'A'+i, i));
char ch;
cout << "Please enter the key: ";
cin >> ch;
map<char, int> :: iterator p;
p = m.find(ch);
if(p != m.end())
cout << p->second << \n';
else
cout << "This key isn't been in map\n";
return 0;
}