1. ホーム
  2. c++

[解決済み] ベクトルから要素を消去する

2022-09-26 21:11:10

質問

eraseメソッドを使ってベクターからある要素を消去したい。しかし、ここで問題なのは、その要素がベクター内に一度だけ出現するとは限らないということです。複数回出現する可能性があり、それらをすべて消去する必要があります。私のコードは次のようなものです。

void erase(std::vector<int>& myNumbers_in, int number_in)
{
    std::vector<int>::iterator iter = myNumbers_in.begin();
    std::vector<int>::iterator endIter = myNumbers_in.end();
    for(; iter != endIter; ++iter)
    {
        if(*iter == number_in)
        {
            myNumbers_in.erase(iter);
        }
    }
}

int main(int argc, char* argv[])
{
    std::vector<int> myNmbers;
    for(int i = 0; i < 2; ++i)
    {
        myNmbers.push_back(i);
        myNmbers.push_back(i);
    }

    erase(myNmbers, 1);

    return 0;
}

このコードが明らかにクラッシュするのは、ベクターを反復している間にベクターの終わりを変えているからです。これを実現する最良の方法は何でしょうか?すなわち、ベクトルを何度も反復したり、ベクトルのコピーをもう1つ作成したりせずに、これを行う方法はありますか?

どのように解決するのですか?

この場合 remove/erase イディオム :

std::vector<int>& vec = myNumbers; // use shorter name
vec.erase(std::remove(vec.begin(), vec.end(), number_in), vec.end());

何が起こるかというと remove は、削除される値と異なる要素を圧縮します ( number_in )の先頭で vector を返し、その範囲の後の最初の要素へのイテレータを返します。次に erase はこれらの要素(その値は不特定)を削除します。