c++迭代器双循环

c++ iterators double loops

本文关键字:双循环 迭代器 c++      更新时间:2023-10-16

我正在尝试做如下操作:

myvec是Couple对象的向量(每个对象由EntityA和EntityB组成)。我正试图删除重复的情侣。。无论如何,有时以下代码会因it2越界而崩溃。条件很好,迭代器似乎不是

if(myvec.size()>1)
for(vector<Couple>::iterator it1 = myvec.begin(); it1+1 !=myvec.end();){
    for(vector<Couple>::iterator it2 = it1+1; it2 !=myvec.end();){
        if((it1->EntityA!=it2->EntityA&&it1->EntityA!=it2->EntityB)||
            (it1->EntityB!=it2->EntityA&&it1->EntityB!=it2->EntityB)){
                it2++;
        }
        else{
            myvec.erase(it2);
        }
    }
    it1++;
}

有什么解决方案/替代方案吗?

尽可能使用现有的库函数。您需要提供一个二进制谓词函数,或者为Couples对象提供一个operator<operator==

std::sort(myvec.begin(), myvec.end());
myvec.erase(std::unique(myvec.begin(), myvec.end()), myvec.end());

但是,最好有一个容器,可以自动避免重复,如std::set。这是一个相关的问题,答案很好。

if(myvec.size()>1)
for(vector<Couple>::iterator it1 = myvec.begin(); it1+1 !=myvec.end();){
    for(vector<Couple>::iterator it2 = it1+1; it2 !=myvec.end();){
        if((it1->EntityA!=it2->EntityA&&it1->EntityA!=it2->EntityB)||
            (it1->EntityB!=it2->EntityA&&it1->EntityB!=it2->EntityB)){
                it2++;
        }
        else{
            it2 = myvec.erase(it2);
        }
    }
    it1++;
}

返回值指向的新位置的随机访问迭代器函数擦除的最后一个元素后面的元素调用,如果操作擦除了最后一个元素,则为矢量结束在序列中。

http://cplusplus.com/reference/stl/vector/erase/

修改要迭代的向量(在这种情况下,在组件之间移动并更改向量长度)不是一个好主意。这就是代码的问题所在。当移除矢量中间的一个分量时,末端的分量会向左移动,因此矢量的末端会移动。这会打乱你的休息状态。

您可以创建一个新的向量-空向量,并将要保留的每个分量添加到其中,而不是修改现有的向量。这可能会消耗更多的内存(如果你的向量很大,那可能很有趣),但它应该会为你节省很多cpu-time,因为删除向量中间的组件不是一个便宜的操作。它右边的所有组件都必须一次一次地移动一个位置(stl中存在没有这个问题的容器)。因此,构建一个新的矢量并添加到其中应该会更好。