Russian Qt Forum
Май 05, 2024, 18:52 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Устройство контейнеров map и hash_map  (Прочитано 6260 раз)
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« : Январь 20, 2015, 11:50 »

Привет, друзья!
Пытаюсь более углублённо познать cpp но никак не могу разобраться с некоторыми моментами. Попытавшись заглянуть под капот STL просто увидел кучу буковок... В связи с этим прошу вас помочь.
Как я понял, принцип работы map и hash_map примерно одинаковый, только в первом случае идет дополнительная проверка ключей с помощью operator<(), что даёт нам упорядоченность по алфавиту. В hash_map же используется operator==().
Первое, что здесь не понятно - это объявления (переписываю из книжки Страуструпа)
Код
C++ (Qt)
template<class Key, class T, class Cmp=less<Key>, class A=allocator<pair<const Key,T> > >
class std::map
{
   // ...
};
template<class Key, class T, class H = Hash<Key>, class EQ = equal_to<Key>, class A = allocator<pair<const Key, T> > >
class hash_map
{
   // ...
};
кто такие less, Hash и equal_to? Я это расценил как имена неких функций, объявление которых я не нашёл.

Также мне никак не разобраться в принципе хранения. Для hash_map написано следующее:
Код
C++ (Qt)
class hash_map
{
   // ...
vector<Entry> v;          // истинные входы
vector<Entry*>b;         // хэш-таблица: указатели внутрь v
   // ...
};
И приведён рисунок

Мне не совсем понятно назначение b. Почему бы просто не иметь массив структур Entry?
« Последнее редактирование: Январь 20, 2015, 13:27 от __Heaven__ » Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #1 : Январь 20, 2015, 13:41 »

Нашёл в STL std::less. Это структура наследованная от std::binary_function. У less определена функция
Код
C++ (Qt)
bool operator()(x,y)
. Насчёт массива указателей понял, что вызывается хэш-функция, которая предоставляет некий uchar, остаток от деления которого на размер массива будет необходимый индекс указателя. По указателю мы получаем список Entry и ищем нужный нам ключ.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #2 : Январь 26, 2015, 10:45 »

Устройство map и hash_map совершенно/принципиально различно. Как Вы знаете, hash хранит данные "по корзинам" (bins), основная идея - спрыгнуть на нужную корзину по остатку от деления. Но надо как-то хранить данные и в каждой корзине. Поэтому сами данные хранятся в первом контейнере "беспорядочно", но имеют указатели на предыдущий и следующий в той же корзине. А головы этих списков хранятся в контейнере указателей

По указателю мы получаем список Entry и ищем нужный нам ключ.
Точнее нужный эл-т оператором ==. (хеш-ключ не уникален)
« Последнее редактирование: Январь 26, 2015, 10:47 от Igors » Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #3 : Январь 26, 2015, 12:02 »

Да, с этим я разобрался. А что же в случае с map?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #4 : Январь 26, 2015, 12:40 »

Да, с этим я разобрался. А что же в случае с map?
Там гораздо более сложная организация данных известная как "красно-черное дерево"
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #5 : Январь 26, 2015, 13:41 »

Слышал о таком. Спасибо.
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4349



Просмотр профиля
« Ответ #6 : Январь 26, 2015, 14:17 »

Для Qt контейнеров есть простая вводная статья:
http://doc.qt.digia.com/qq/qq19-containers.html
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #7 : Январь 26, 2015, 17:55 »

Для Qt контейнеров есть простая вводная статья:
http://doc.qt.digia.com/qq/qq19-containers.html
Спасибо, Old. Я понял исходя из картинки, что QMap производит поиск как по методу половинного деления.
На некоторых картинках фигурируют QBasicAtomic. Из описания не понял назначения. Как вектор можно использовать в мультипоточности?
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4349



Просмотр профиля
« Ответ #8 : Январь 26, 2015, 18:49 »

На некоторых картинках фигурируют QBasicAtomic. Из описания не понял назначения. Как вектор можно использовать в мультипоточности?
Атомарный там счетчик, для организации потоко-безопасного implicit share.
Это позволяет безопасно передавать коллекции между потоками, без реального копирования данных.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.112 секунд. Запросов: 23.