2015-03-04 2 views
4

Я реализую карту с несколькими индексами в C++ 11, которую я хочу оптимизировать для определенных функций. Проблема, которую я сейчас пытаюсь решить, состоит в том, чтобы не хранить ключевые элементы более одного раза. Но позвольте мне объяснить.Реализация карты с несколькими индексами на C++

Проблема возникла при сортировке гистограмм для их наложения в разные комбинации. Гистограммы имели имена, которые можно было разделить на маркеры (свойства).

Вот особенности я хочу, чтобы моя карта свойство иметь:

  1. Уметь перебрать свойства в любом порядке;
  2. Возможность возврата контейнера с уникальными значениями для каждого свойства;
  3. Накопить значения свойств в том порядке, в котором они поступают, но иметь возможность сортировать свойства с помощью пользовательского оператора сравнения после заполнения карты;

У меня есть working implementation в C++ 11, используя std::unordered_map с std::tuple как key_type. Я накапливаю значения свойств, когда они поступают в кортеж forward_lists. Предполагаемое использование - перебирать списки для создания ключей.

Оптимизация, которую я хотел бы представить, заключается в том, чтобы хранить только свойства свойств в списках и не хранить их в кортежах, используемых в качестве ключей на карте. Я хотел бы сохранить способность иметь функции, возвращающие ссылки на ссылки на списки значений свойств, а не списки некоторых оболочек.

Я знаю, что boost::multi_index имеет аналогичную функциональность, но мне не нужны накладные расходы при сортировке по мере поступления ключей. Я бы хотел, чтобы новые значения свойств хранились последовательно и только сортируемый postfactum. Я также посмотрел boost::flyweight, но в простейшем подходе списки будут тогда flyweight<T> вместо T, и я бы не хотел этого делать. (Если это лучшее решение, я определенно мог бы с ним жить.)

Я знаю, что списки стабильны, т. Е. Как только элемент создан, его указатель и итератор остаются в силе даже после вызова list::sort(). Зная, что можно что-то сделать с картой, чтобы устранить избыточные копии элементов кортежа? Может ли помочь вам использовать специализированный распределитель карт?

Спасибо за предложения.

+0

Итак, вам нужна структура с ключами unqiue, но без сортировки? Как это возможно? Вам нужно, чтобы ваш контейнер сортировался, чтобы иметь возможность эффективно проверять, существует ли элемент с определенным ключом в контейнере. Я думаю, что реализация unordered_map - хорошая идея. – jPlatte

+0

Кроме того, я не рассматривал его подробно, но я заметил одно: вы создали свою собственную структуру хэширования, которую вы передали в экземпляр шаблона unordered_map в качестве третьего параметра.Вы также можете (частично, в вашем случае) специализироваться на std :: hash. Это просто альтернатива, хотя я не думаю, что это повлияет на поведение или производительность. Одна вещь, которую вы должны изменить, - это имя вашего пространства имен; имена с двумя ведущими символами подчеркивания зарезервированы для использования в компиляторах и стандартных библиотеках: http://stackoverflow.com/q/228783/1592377 – jPlatte

+0

@jPlatte: Я не прошу сортировки. Я просто прошу не хранить повторяющиеся данные. Например, карта может хранить указатели на ключевые части, хранящиеся в списках. Карта может сортировать указатели столько, сколько им нравится. PS: Я не знал об условном названии пространства имен. Спасибо за совет. – SU3

ответ

1

Ваша карта должна быть от кортежей итераторов до ваших контейнеров-опоры.

Напишите хэш разыменования итераторов и объедините результат.

Замените форвардные перечни контейнеров с наборами, которые в первом порядке обозначают хэш, а затем содержимое.

Сделайте поиск первым, находящимся в наборе, а затем выполнив поиск в хеше.

Если вам нужен другой заказ для реквизита, у вас есть другой контейнер с итераторами.

+0

Я уже рассматривал это, но недостаток заключается в том, что в этой реализации я не могу написать функцию get, которую я мог бы использовать так: 'for (auto & p: mymap.get <0>()) {...}' для итерации по определенному свойству, без p-типа указателя или итератора. Или я могу добавить список в мой класс хранения ссылок? Могу ли я сделать это 'std :: forward_list >'? – SU3

+0

@ivan или написать итератор разыменования итератора? – Yakk

+0

Вы имеете в виду написать класс для возвращаемой функции get, который будет реализовывать функции begin() и end(), возвращающие итератор, такие как объекты, которые детерминируют ссылки на T? – SU3

Смежные вопросы