简体   繁体   中英

Erasing the last element of a vector by looping through it

I want to loop through a vector and erase certain elements that correspond to a certain criteria, for example:

vector<int> myvector;
vector<int>::iterator it;

myvector.push_back(1);
myvector.push_back(2);
myvector.push_back(3);
myvector.push_back(4);

for(it = myvector.begin(); it != myvector.end(); ++it){

    if((*it) == 4){
        it = myvector.erase(it);
    }
}

Now this works fine unless the criterion erases the last item like in the code above. How do you avoid this behaviour ?

Thanks.

EDIT------------------------------------

Now the reason I was looping through it was that there are actually 4 vectors I need to delete the element from (but the criterion is only on one vector):

In this case, is this how to go ?

vector<int> myvector;
vector<int> myvector2;
vector<int> myvector3;
vector<int> myvector4;
vector<int>::iterator it;
vector<int>::iterator it2;
vector<int>::iterator it3;
vector<int>::iterator it4;

myvector.push_back(1);
myvector.push_back(2);
myvector.push_back(3);
myvector.push_back(4);

(assume myvector2/3/4 have values inside them)

it2 = myvector2.begin()
it3 = myvector3.begin()
it4 = myvector4.begin()

for(it = myvector.begin(); it != myvector.end();){

    if((*it) == 4){
        it = myvector.erase(it);
        it2 = myvector2.erase(it2);
        it3 = myvector3.erase(it3);
        it4 = myvector4.erase(it4);
    }
    else{
    ++it;
    ++it2;
    ++it3;
    ++it4;
    }
}

Is there a modification to the erase/remove idiom valid in this case ?

The usual is the remove/erase idiom, which would look something like this:

myvector.erase(std::remove(myvector.begin(), myvector.end(), 4), myvector.end());

Edit: Rereading your question, you mention "certain criteria". If the criteria aren't necessarily just removing a single value, you can use std::remove_if instead of std::remove , and specify your criteria in a functor.

Edit2: for the version dealing with four vectors, the usual method is to create a struct holding the four related values, and delete entire structs:

struct x4 { 
    int a, b, c, d;

    // define equality based on the key field:
    bool operator==(x4 const &other) { return a == other.a; }

    x4(int a_, int b_=0, int c_=0, ind d_=0) : a(a_), b(b_), c(c_), d(d_) {}
};

std::vector<x4> myvector;

myvector.erase(std::remove(myvector.begin(), myvector.end(), x4(4));

Again, if your criteria are more complex than you can easily express in a comparison operator, you can use std::remove_if instead of std::remove . This is also useful if/when you might need to apply different criteria at different times.

If you really need to keep your data in parallel vectors (eg, you're feeding the data to something external that requires separate, contiguous arrays), then using a loop is probably as good as the alternatives.

不要使用for循环来执行此操作,已经为您准备了调试良好的算法。

myvector.erase(std::remove(myvector.begin(), myvector.end(), 4), myvector.end());

I think you should write the loop as :

for(it = myvector.begin(); it != myvector.end(); )
{
    if((*it) == 4)
        it = myvector.erase(it);
    else
        ++it; //increment here!
}

Because in your code, if you find 4 , you update it in the if block itself, but after that you again increment/update it in the for also which is wrong. That is why I moved it to else block that ensures that it gets incremented if you don't find 4 (or whatever value you're searching).

Also remember that erase returns iterator pointing to the new location of the element that followed the last element erased by the function call .

for(it = myvector.begin(); it < myvector.end(); ++it){

    if((*it) == 4){
        it = myvector.erase(it);
    }
}

This will make sure your loop will break if the it >= myvector.end() .

erase通常与remove (也可以查看删除删除习惯用法),如下所示

myvector.erase(std::remove(myvector.begin(), myvector.end(), 4), myvector.end());

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