Re: слияние контейнеров
От: _DAle_ Беларусь  
Дата: 16.04.06 21:50
Оценка:
Здравствуйте, cthutq00, Вы писали:

C>
C>enum T {A, B, C, D, E};
C>struct S{
C>    T type;
C>    int count;
C>    S (T t, int c) : type (t), count (c){;}

C>    bool operator == (const S& s){
C>        return type == s.type;
C>    }
C>    void operator += (const S& s){
C>        count += s.count;
C>    }
C>    void operator << (const S& s){
C>        type = s.type;
C>        count += s.count;
C>    }

C>};

C>const S operator+ (const S& lhs, const S& rhs){
C>    return S (lhs.type, lhs.count + rhs.count);
C>}

C>


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

C>1. Есть вектор объектов


C>
C>    std::vector<S> v1(3);
C>    std::vector<S> v2(3);

C>


C>нужно каждый элемент 1 списка объединить с каждым элементом второго

C>я смог это сделать только так

Я так понял, что не каждый с каждым, а сложить соответствующие элементы векторов.

C>
C>    std::transform (v1.begin(), v1.end(),
C>            v2.begin(), v1.begin(),
C>            std::plus<S>());

C>

Ну вместо transform лучше использовать merge, мне кажется, в данном случае.

C>но для каждой пары создается новый объект и перезаписывается на место в 1 векторе

C>получается слишком много вызовов конструкторов и деструкторов

Хм, ну тогда
    for (unsigned i = 0; i < v1.size(); ++i)
        v1[i] += v2[i];

Никаких конструкторов и деструкторов и читается хорошо. По-хорошему индексную переменную надо заменить на итераторы, но из-за компактности написал так.

C>2. есть список


C>
C>    std::list<S> list;
C>    list.push_back(S (A, 50));
C>    list.push_back(S (B, 200));
C>    list.push_back(S (C, 300));
C>    list.push_back(S (A, 50));

C>

C>нужно объединить равные объекты
C>тоесть должно получиться в списке
C>S (A, 100);
C>S (B, 200);
C>S (C, 300);

Предлагаю завести map<T, int>, проитерироваться по списку, сбрасывая все в map, а потом построить новый list по полученному map'у. Если же enum никогда изменяться не будет (но вообще, лучше не делать таких предположений обычно), можно вместо map'a воспользоваться vector<int>.

C>3. нужно сделать тоже если они в разных списках


C>
C>    std::list<S> list1;
C>    list1.push_back(S (A, 50));
C>    list1.push_back(S (B, 200));
C>    list1.push_back(S (C, 300));

C>    std::list<S> list2;
C>    list2.push_back(S (A, 50));
C>    list2.push_back(S (E, 500));

C>


C>тоесть А из второго списка должен объединиться с А из первого списка и удалиться из 2

C>в результате должно получиться

C>list1;

C>S (A, 100);
C>S (B, 200);
C>S (C, 300);

C>list2;

C>S (E, 500);

Тут на самом деле не совсем понятно, что надо сделать. Предлагаю тоже самое, сначала забрасываем в map первый список, потом выборочно (проверяем, если такой элемент в map'е) забрасываем в map второй вместе с удалением забрасываемых элементов из самого списка.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.