Здравствуйте, Olivia, Вы писали:
O>Здравствуйте, Кодт, Вы писали:
O>Большое спасибо за ответ.
К>>Есть несколько вариантов:
К>>1) изначально хранить в структуре, поддерживающей несколько порядков в контейнере — bimap, boost::multi_index...
К>>2) сделать "слепок" контейнера и отсортировать. Вместо копирования значений можно брать указатели/итераторы исходного контейнера.
O>В первом случае, могли бы наглядно показать как это делается
O>вот мой класс
O>class Temp
O>{
O> public:
O> char s[50];
O> int age;
O> Temp();
O> Temp(const Temp &T);
O> Temp(char t_s[50],int t_age);
O> ~Temp();
O>};
O>Как тогда будет выглядеть сама функция сортировки, она же там требует три параметра.
Вот здесь
http://www.boost.org/libs/multi_index/doc/tutorial.html
рассказывается о том, как создавать многоиндексные контейнеры.
Кстати, пример там практически один в один с твоим
O>Во втором случае. Я не знакома с понятием слепок контейнера, где бы мне можно было почитать об этом. И я так понимаю во втором случае сортировка будет производиться по итераторам?
O>Я просто не могу понять сам механизм, ведь данные в ассоциативных контейнерах хранятся в упорядоченном виде по ключу, каким образом они будут упорядычиваться, если применить один из предложенных вариантов.
Слепок в данном случае — это коллекция (вектор/список/множество) элементов, содержащихсч в исходном контейнере.
Если копировать элементы дорого, то можно и нужно формировать коллекцию посредников — указателей, итераторов и т.п.
Имхо, наиболее эффективным по скорости будет вектор указателей — единожды выделяется блок памяти, за линейное время туда копируются указатели на элементы, и наконец, выполняем сортировку.
bool less_name_fn(const Temp& l, const Temp& r); // по полю s
bool less_age_fn (const Temp& l, const Temp& r); // по полю age
struct less_name { bool operator()(const Temp& l, const Temp& r) const { return less_name_fn(l,r); } };
typedef std::set<Temp, less_name> temps_by_name;
struct less_ptr_age { bool operator()(const Temp* l, const Temp* r) const { return less_age_fn(*l,*r); } };
void print_by_age(const temps_by_name& temps)
{
tyepdef std::vector<Temp*> temp_ptrs_by_age;
temp_ptrs_by_age v; v.reserve(temps.size());
for(temps_by_name::const_iterator i = temps.begin(); i!=temps.end(); ++i)
v.push_back(&*i);
std::stable_sort(v.begin(), v.end(), less_ptr_age()); // ещё и порядок имён сохраним
for(temp_ptrs_by_age::const_iterator j = v.begin(); j!=v.end(); ++j)
cout << (*j).s << " : " << (*j).age << endl;
}
O>И какой из вариантов наиболее эффективен?
Зависит от того, как часто тебе нужно перечислять элементы по вторичному индексу.