Re[5]: Однообразность в STL
От: Кодт Россия  
Дата: 07.12.04 13:47
Оценка:
Здравствуйте, 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>И какой из вариантов наиболее эффективен?


Зависит от того, как часто тебе нужно перечислять элементы по вторичному индексу.
Перекуём баги на фичи!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.