Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
OOAP.doc
Скачиваний:
0
Добавлен:
01.03.2025
Размер:
494.59 Кб
Скачать

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;

}

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