vector :: erase()会改变位置吗?

use*_*128 2 c++ vector erase

这是我的问题,我有一个双向量,我需要在一定条件下消除它们中的一些.这是一个代码示例:

 vector <double> appo;
 for(int i=0;i<appo.size();i++){
       for(int j=i+1;j<appo.size();j++){
         if( condition(appo[i],appo[j]) ){
           appo.erase(appo.begin()+j);
           j--;
         }
       }
    }
Run Code Online (Sandbox Code Playgroud)

因为在擦除()之后我的大小减少了1并且所有元素左移左移,所以减少j是正确的吗?

好吧我决定不使用removeif,因为它是一个小程序,我现在不关心性能,但我得到了分段错误.这是代码:

vector <double> *point;
for(int i=0;i<point->size();i+=3){
     for(int j=i+3;j<point->size();j+=3){
       if(distance((*point)[i],(*point)[i+1],(*point)[i+2],(*point)[j],(*point)[j+1],(*point)[j+2]) < treshold){
         point->erase(point->begin()+j,point->begin()+j*3);
         j-=3;
       }
     }
  }
Run Code Online (Sandbox Code Playgroud)

point是一个坐标向量,如(x1,y1,z1,x2,y2,z3,...,xn,yn,zn).任何的想法?

Ste*_*sop 6

递减是正确的j,因为在删除索引处j的元素之后,之前处于的元素j+1现在处于j,所以您希望使用相同的值再次重复循环j.减少它有这种效果,因为循环本身会增加它.

您还可以考虑使用迭代器而不是索引:

vector<double>::iterator j = appo.begin() + i + 1;
while (j != appo.end()) {
    if (condition(appo[i], *j)) {
        j = appo.erase(j);
    } else {
        ++j;
    }
}
Run Code Online (Sandbox Code Playgroud)

完成后,您也可以使用迭代器i.

正如"eq-"在评论中所说,有一种标准算法可以帮助你.任你选,你是否更愿意在可用性方面的循环,但它通常是更有效,因为一边喊"擦除"洗牌沿着一步一个时间每一个元素,而remove_if跟踪"读取位置"和"写位置"所以它最多只复制一次每个元素.

appo.erase(
    appo.remove_if(
        appo.begin() + i + 1,
        appo.end(),
        ShouldRemove(appo[i])
    ),
    appo.end()
);
Run Code Online (Sandbox Code Playgroud)

在C++ 03中,您必须定义ShouldRemove类似于:

struct ShouldRemove {
    double lhs;
    ShouldRemove(double d) : lhs(d) {}
    bool operator()(double rhs) {
        return condition(lhs, rhs);
    }
};
Run Code Online (Sandbox Code Playgroud)

在C++ 11中,您可以使用lambda而不是ShouldRemove:

appo.erase(
    appo.remove_if(
        appo.begin() + i + 1,
        appo.end(),
        [&](double d) { return condition(appo[i], d); }
    ),
    appo.end()
);
Run Code Online (Sandbox Code Playgroud)

您还可以使用std::bind1stboost::bind(在C++ 03中)或std::bind(在C++ 11中)使用某些选项,但要正确理解这些选项非常棘手.