Можно ли изменить компаратор C ++ std :: set? - PullRequest
5 голосов
/ 15 октября 2011

У меня есть набор данных, которые в некоторых случаях мне нужно сортировать их одним способом, а некоторые - другим способом. Например, предположим, что набор данных представляет собой набор строк, {"abc", "dfg", ...}. Иногда мне нужно отсортировать их в алфавитном порядке, а иногда сравнивая их длину.

Изначально я использовал std :: set в качестве контейнера моих данных и реализовал 2 компаратора, надеясь, что смогу изменить компаратор набора на лету, потому что данные огромны, и копировать их из не очень хорошая идея один набор другому ... я просто хочу отсортировать его, используя разные компараторы время от времени. Это возможно или как правильно это сделать?

Ответы [ 3 ]

6 голосов
/ 15 октября 2011

Вы должны указать компаратор std::set во время строительства.

В качестве решения я бы вместо этого поддерживал два набора «индексов», каждый из которых ссылается на фактическую коллекцию. Это дало бы наибольшую гибкость. Чтобы сохранить все вместе, я предлагаю вам обернуть это в один класс:

// to be compiled, debugged etc..., but ideal
// to grab  the idea
// caveats: maintain the index objects whenever the collection
// gets resized/reallocated etc...
// so not to be written yourself, use an existing library :)
template< typename T, typename comp1, typename comp2 >
struct MultiIndex {
    std::deque<T> collection;
    std::set<T*, comp1> index1;
    std::set<T*, comp2> index2;

    void insert( const T& t ){
       collection.push_back(t);
       index1.insert( &collection.back() );
       index2.insert( &collection.back() );
    }
};

В библиотеке повышения есть такой класс: Мультииндекс .

2 голосов
/ 15 октября 2011

Набор внутренне всегда сохраняется отсортированным (иначе у вас не будет необходимой производительности), поэтому нет, компаратор не может быть изменен.Я думаю, что лучшее решение здесь - поддерживать два набора с одинаковыми данными, но с разными компараторами.Я бы инкапсулировал два набора в классе, и чтобы такие функции, как вставка, работали в обоих наборах, чтобы гарантировать одинаковость данных в обоих наборах.

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

1 голос
/ 15 октября 2011

Нет, не на лету.Дерево строится на основе критериев сортировки, указанных во время построения.Вы говорите о построении нескольких индексов в одном наборе данных, что может быть достигнуто несколькими наборами.Вероятно, есть много таких библиотек, как boost, для которых уже есть что-то созданное.

...