STL карта, как структура данных, чтобы позволить поиск на основе двух ключей

0

Я хочу создать такую карту, как структура, чтобы разрешить поиск двумя клавишами, и будут строками, вот пример:

Myclass s;

Лицо p = s.find("Давид"); //поиск по имени

// OR

p = s.find("XXXXX"); // поиск по ID

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

Теги:
list
vector
stl
map

2 ответа

2
Лучший ответ

Поместите свои записи в вектор (или список). Добавьте указатель на объекты записи на две карты: одну с одним ключом и одну с другой.

  • 0
    С некоторой работой вы могли бы даже использовать std::set_intersection чтобы найти ответ.
0

Существует много разных способов достижения этой цели. Возникает вопрос: каковы сложности операций вставки, удаления и поиска, на которые вы нацелены?

std::map реализуется как красно-черное дерево, которое обеспечивает невероятно быструю самобалансировку (вращение) и все упомянутые операции (поиск/поиск, вставка, удаление) со сложностью O(log(n)). Обратите внимание, что это соответствует идее одного ключа.

С помощью двух клавиш вы не можете сохранять элементы отсортированными, потому что порядок, основанный на одном ключе, будет, скорее всего, отличаться от порядка, основанного на другом. Самый простой и естественный подход - хранить записи в одном контейнере и удерживать ключи, используемые этим контейнером, в двух разных структурах, один из которых оптимизирован для извлечения этого ключа, данного id а другой для получения его name.

Если есть ограничение на хранение всего в одном месте, в то время как вы хотите оптимизировать операцию поиска, которая будет поддерживать два разных ключа, тогда вы можете создать оболочку std::map<std::string, Person> где каждый элемент будет (каждый раз под другим ключом), то есть что-то вроде:

std::map<std::string, Person> myContainer;
...
Person p;
std::string id = "1E57A";
std::string name = "David";
myContainer[id] = p;
myContainer[name] = p;
Я могу придумать 2 преимущества этого:
  • вполне удовлетворительная производительность:
    • поиск со сложностью O(log(2*n))
    • вставка и удаление со сложностью O(2*log(2*n))
  • чрезвычайно простая реализация (с использованием существующего контейнера)
    • вам просто нужно помнить, что "ожидаемый" размер контейнера составляет половину его фактического размера
    • оба ключа: id и name должны быть атрибутами Person так что, когда вы найдете конкретный элемент с одним из этих ключей, вы сразу же получите другой
Недостатком является то, что он будет потреблять 2x столько памяти, и может быть даже ограничение:
  • ни одно из name должно быть id какого-либо другого человека одновременно и наоборот (ни один id должен быть name какого-либо другого лица)
  • 0
    O (log (2 * n)) - сложность просто O (log (n)). Это не очень хорошая система, чтобы говорить о константах и факторах.
  • 0
    @woolstar: O(log(2*n)) - это просто более точная оценка, которая явно выражает стоимость удвоения размера контейнера.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню