0

我正在尝试执行以下操作:

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++;
}

任何解决方案/替代方案?

4

3 回答 3

3

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

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

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

于 2012-07-12T20:56:04.137 回答
2
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/

于 2012-07-12T20:49:11.967 回答
1

修改您正在迭代的向量(在这种情况下移动组件并更改向量长度)不是一个好主意。那是你的代码的问题。当您删除向量中间的一个分量时,末端的分量会向左移动,因此向量的末端会移动。这会破坏你的休息条件。

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

于 2012-07-12T20:52:57.517 回答