简体   繁体   中英

How can I remove elements of vectors in a set of vectors?

If I have a set of unique vectors, how can I (for example) delete the second element in each vector? I have created the following simple example:

#include <iostream>
#include <vector>
#include <set>
#include <string>

using namespace std;

int main()
{
    vector<int> myVec1 = {0, 1, 2, 3, 4, 5};
    vector<int> myVec2 = {3, 5, 7, 2, 4, 1};
    vector<int> myVec3 = {2, 5, 3, 8, 6, 9};

    set<vector<int>> mySet;
    mySet.insert(myVec1);
    mySet.insert(myVec2);
    mySet.insert(myVec3);

    // right now this for loop deletes an element from a copy only
    for(auto item : mySet) item.erase(item.begin() + 2);

    for(auto item : mySet)
    {
        for(auto element : item) cout << " " << element;
        cout << "\n";
    }
}

This example can be compiled and run on cpp.sh .

Possible solutions I have considered:

  • Using for(auto& item : mySet) ; however, this gives an error on compilation (no matching member function for call in const vector)
  • Using an iterator ( gives a similar error )

I would use std::transform to take the data from the existing set, modify as needed, and insert the results into a new set, then swap the old set with the new one:

std::set<std::vector<int> > mySet { 
    {0, 1, 2, 3, 4, 5},
    {3, 5, 7, 2, 4, 1},
    {2, 5, 3, 8, 6, 9}
};

std::set<std::vector<int>> temp;

std::transform(mySet.begin(), mySet.end(), 
    std::inserter(temp, temp.end()), 
    [](std::vector<int> s) { s.erase(s.begin() + 1); return s; }
);

std::swap(temp, mySet);

If you're dealing with a lot of data, you might be better off getting a vector from the input set, erasing it from the input set, erasing the element from that vector, and inserting the result into the output.

Probably not the solution you're looking for, but you could have your set hold pointers to vectors instead. This works for me:

int main() {

    vector<int> myVec1 = {0, 1, 2, 3, 4, 5};
    vector<int> myVec2 = {3, 5, 7, 2, 4, 1};
    vector<int> myVec3 = {2, 5, 3, 8, 6, 9};

    set<vector<int>*> mySet;
    mySet.insert(&myVec1);
    mySet.insert(&myVec2);
    mySet.insert(&myVec3);

    for(vector<int>* item : mySet) item->erase(item->begin() + 2);

    for(vector<int>* item : mySet)
    {
        for(auto element : *item) cout << " " << element;
        cout << "\n";
    }

    return 0;
}

You would need to remove the vector from the set of vectors before manipulating it and after the manipulation reinsert the vector.

Since this would involve a lot of creating/copying vectors, you could use pointers to vectors -- in which case you would need your own compare function object:

struct compare
{        bool operator()(
                 const std::shared_ptr<std::vector<int> > &_r0,
                 const std::shared_ptr<std::vector<int> > &_r1) const
         {        return *_r0 < *_r1;
         }
};
std::set<std::shared_ptr<std::vector<int> >, compare> sSet;

in order to delete the second element in each vector, I would first create a copy of all pointers:

std::vector<std::shared_ptr<std::vector<int> > > sCopy(
        sSet.begin(),
        sSet.end());
sSet.clear();
for (auto p = sCopy.begin(), pEnd = sCopy.end();
        p != pEnd;
        ++p)
{        auto rVectorPtr = *p;
         if (rVectorPtr->size() > 1)
                 rVectorPtr->erase(rVectorPtr->begin() + 1);
         sSet.insert(rVectorPtr);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM