2

これが私の質問です。私はdoubleのベクトルを持っており、特定の条件下でそれらのいくつかを排除する必要があります。コード例は次のとおりです。

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

destroy()の後、私のサイズは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;
       }
     }
  }

ポイントは座標のベクトルなので、(x1、y1、z1、x2、y2、z3、...、xn、yn、zn)のようになります。何か案が?

4

1 に答える 1

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

それが済んだら、イテレータを使用することもできますi

「eq-」がコメントで言っているように、あなたを助けることができる標準的なアルゴリズムがあります。使いやすさの点でループよりも好きかどうかを選択してください。ただし、「消去」を繰り返し呼び出すと、各要素が一度に1ステップずつシャッフルされremove_if、「読み取り位置」と「書き込み位置」が追跡されるため、一般的に効率的です。 "、したがって、各要素を最大で1回だけコピーします。

appo.erase(
    appo.remove_if(
        appo.begin() + i + 1,
        appo.end(),
        ShouldRemove(appo[i])
    ),
    appo.end()
);

C ++ 03では、次のように定義する必要がありますShouldRemove

struct ShouldRemove {
    double lhs;
    ShouldRemove(double d) : lhs(d) {}
    bool operator()(double rhs) {
        return condition(lhs, rhs);
    }
};

C ++ 11では、ShouldRemoveの代わりにラムダを使用できます。

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

std::bind1stor boost::bind(C ++ 03の場合)または(C ++ 11の場合)を使用するオプションもいくつかありますstd::bindが、それらを正しく理解するにはかなり注意が必要です。

于 2012-09-04T19:24:23.903 に答える