Вычитание и пересечение двух векторов указателей в C ++ - PullRequest
1 голос
/ 05 августа 2011

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

Моя пользовательская структура классов:

<code>
Class Item
{
   string ItemId;
   string ItemDescription;
   float ItemPrice;
}
Первый вектор ( V1 ) содержит n записей и второй вектор ( V2 ) имеет m записей (n> m) .

Я должен выполнить две операции:

Получить вектор с общими объектами в V1 и V2 . Обычно я имею в виду, что ItemId для элементов одинаков. (Может обозначаться как Пересечение V1 и V2 ).

Получите вектор, элементы которого отсутствуют в V2 .(Может именоваться V1-V2 ).

Как это сделать эффективно ??

Ответы [ 3 ]

5 голосов
/ 05 августа 2011

Вот пример того, как сделать это, используя STL set_intersection и set_difference, чтобы получить то, что вы хотели:

class Item
{
public:
    Item(int i):ItemId(i){}

   int ItemId;
   string ItemDescription;
   float ItemPrice;

   bool operator<(const Item& rhs)
   {
       return ItemId < rhs.ItemId;
   }
   bool operator==(const Item& rhs)
   {
       return ItemId == rhs.ItemId;
   }
};

int main()
{
    std::vector<Item> myvec1;
    myvec1.push_back(Item(1));
    myvec1.push_back(Item(2));
    myvec1.push_back(Item(1));
    myvec1.push_back(Item(10));
    myvec1.push_back(Item(5));
    myvec1.push_back(Item(3));
    myvec1.push_back(Item(10));


    std::vector<Item> myvec2;
    myvec2.push_back(Item(10));
    myvec2.push_back(Item(1));
    myvec2.push_back(Item(10));
    myvec2.push_back(Item(1));
    myvec2.push_back(Item(3));

    std::sort(myvec1.begin(), myvec1.end());
    std::sort(myvec2.begin(), myvec2.end());

    myvec1.erase(std::unique(myvec1.begin(), myvec1.end()), myvec1.end());
    myvec2.erase(std::unique(myvec2.begin(), myvec2.end()), myvec2.end());

    std::vector<Item> myvec3; //Intersection of V1 and V2
    std::vector<Item> myvec4; //V1-V2
    set_intersection(myvec1.begin(),myvec1.end(), myvec2.begin(),myvec2.end(), std::back_inserter(myvec3)); //myvec3: 1 3 10
    set_difference(myvec1.begin(),myvec1.end(), myvec2.begin(),myvec2.end(), std::back_inserter(myvec4));   //myvec4: 2 5 
}
2 голосов
/ 05 августа 2011

Если вы используете stl, для первой проблемы вы можете использовать set_intersection , для второй set_difference

1 голос
/ 05 августа 2011

@ Amresh, это пример, который вы хотели использовать вектор с указателем.Но я использовал boost :: shared_ptr вместо необработанного указателя, поэтому вам нужно беспокоиться об управлении памятью:

class Item;
typedef boost::shared_ptr<Item> MyPtr;
typedef std::vector<MyPtr> VecType;

class Item
{
public:
    Item(int i):ItemId(i){}
    friend bool operator<(MyPtr lhs, MyPtr rhs);
    friend bool operator==(MyPtr lhs, MyPtr rhs);

   int ItemId;
   string ItemDescription;
   float ItemPrice;

   bool operator<(const Item& rhs)
   {
       return ItemId < rhs.ItemId;
   }
   bool operator==(const Item& rhs)
   {
       return ItemId == rhs.ItemId;
   }
};



bool operator<(MyPtr lhs, MyPtr rhs)
{
    return lhs->ItemId < rhs->ItemId ;
}

bool operator==(MyPtr lhs, MyPtr rhs)
{
    return lhs->ItemId == rhs->ItemId ;
}

int main()
{

    VecType myvec1;
    myvec1.push_back(MyPtr(new Item(2)));
    myvec1.push_back(MyPtr(new Item(1)));
    myvec1.push_back(MyPtr(new Item(10)));
    myvec1.push_back(MyPtr(new Item(5)));
    myvec1.push_back(MyPtr(new Item(3)));
    myvec1.push_back(MyPtr(new Item(10)));

    VecType myvec2;
    myvec2.push_back(MyPtr(new Item(10)));
    myvec2.push_back(MyPtr(new Item(1)));
    myvec2.push_back(MyPtr(new Item(10)));
    myvec2.push_back(MyPtr(new Item(1)));
    myvec2.push_back(MyPtr(new Item(3)));

    std::sort(myvec1.begin(), myvec1.end());
    std::sort(myvec2.begin(), myvec2.end());

    myvec1.erase(std::unique(myvec1.begin(), myvec1.end()), myvec1.end());
    myvec2.erase(std::unique(myvec2.begin(), myvec2.end()), myvec2.end());

    VecType myvec3; //Intersection of V1 and V2
    VecType myvec4; //V1-V2
    set_intersection(myvec1.begin(),myvec1.end(), myvec2.begin(),myvec2.end(), std::back_inserter(myvec3)); //myvec3: 1 3 10
    set_difference(myvec1.begin(),myvec1.end(), myvec2.begin(),myvec2.end(), std::back_inserter(myvec4));   //myvec4: 2 5 
}
...