2012-04-10 2 views
0

Мне нужен длинный список объектов, упорядоченных по одному из параметров. Каков самый быстрый способ сделать это на C++? Мне нужно иметь возможность добавлять и удалять элементы в этот список и по-прежнему сортироваться по этому конкретному параметру.Сортировка объектов с дублирующимися ключами

Class Foo { 
private: 
    int rank; 
} 

Я хочу, чтобы все мои Foo объекты должны быть перечислены в порядке возрастания и , когда новый один добавляется или удаляется он должен принять правильное место в порядке. Также может быть более одного объекта с тем же rank, поэтому значение ключа невозможно.

Любая идея, как я могу это сделать на C++? Я смотрел на make_heap(), но я не уверен, как использовать его (или если он может быть использован) с объектами.

+3

Использование станд :: карта ... –

+0

Вернее станд :: набор - если вам не нужно менять элементы. –

+0

Карта нуждается в уникальном ключе, хотя в моем сценарии возможно, что есть несколько объектов, где параметр объекта, который я хочу заказать, тот же – networkprofile

ответ

2

Сначала вы, вероятно, следует определить operator< для Foo (что-то вроде этого) ...

inline bool operator< (const Foo& lhs, const Foo& rhs) { 
    return lhs.rank < rhs.rank; 
} 

, которые должны быть объявлены в качестве друга Foo-х:

class Foo { 
public: 
    explicit Foo(int rank_init) : rank(rank_init) {} 
    friend bool operator< (const Foo&, const Foo&); 
private: 
    int rank; 
}; 


Теперь вы можете создать std::multiset<Foo>, который сохранит Foo s отсортированный по возрастанию на rank, например

std::multiset<Foo> foo_multiset; 
foo_multiset.insert(Foo(5)); // 5 
foo_multiset.insert(Foo(3)); // 3, 5 
foo_multiset.insert(Foo(1)); // 1, 3, 5 
foo_multiset.insert(Foo(3)); // 1, 3, 3, 5 
size_t erased_count(foo_multiset.erase(Foo(3))); // 1, 5 (erased_count == 2) 

У нас нет гарантий, что это будет «самый быстрый» вариант в вашем конкретном случае. Вам нужно будет профилировать это. В зависимости от количества элементов, частоты операций вставки/стирания и реализации STL вы можете обнаружить, что отсортированный std::vector<Foo> лучше соответствует вашим потребностям.

Скотт Мейерс Effective STL описывает, как это может быть случай в пункте 23.

+0

Как это работает, я вызываю оператор перед добавлением моего объекта в мультимножество ? И что произойдет, если два звания равны? Спасибо за вашу помощь! – networkprofile

+1

'multiset' использует' std :: less', который использует 'operator <' для определения порядка сортировки. Вам не нужно ничего делать, кроме как определить их в соответствии с моим ответом, и вам хорошо идти. 'multiset' обслуживает несколько элементов, ключи которых эквивалентны, поэтому вы сможете сохранить несколько' Foo 'с одинаковыми рангами в контейнере. – Fraser

+0

Еще один вопрос: имеет значение для производительности, упорядочены ли объекты в мультимножестве? Я внес некоторые изменения в свою модель, и мне больше не нужно их заказывать, мне просто нужно быстро получить доступ к элементам с одним и тем же ключом. – networkprofile

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