【C++】vector等から要素を削除する様々な方法を徹底解説

目次

はじめに

C++のコンテナ(vector, list, mapなど)を操作する上で、「特定の要素を削除する」という処理は非常に頻繁に発生します。C++には、この削除処理を行うための様々な方法が用意されており、状況に応じて最適なものを選択することが重要です。

この記事では、コンテナから要素を削除するための主要なテクニックを、以下のカテゴリに分けて網羅的に解説します。

  1. 先頭/末尾の要素を削除
  2. 指定した位置の要素を削除
  3. 条件に一致する要素を削除
  4. mapsetからキーを指定して削除

1. 先頭/末尾の要素を削除する (pop_front, pop_back)

listdeque のような、先頭や末尾への要素の追加・削除が高速に行えるコンテナでは、専用のメンバ関数が用意されています。

サンプルコード

#include <iostream>
#include <list>

using namespace std;

int main() {
    list<int> numbers = {10, 20, 30, 40};
    
    // 先頭要素を削除
    numbers.pop_front(); // -> {20, 30, 40}
    
    // 末尾要素を削除
    numbers.pop_back(); // -> {20, 30}
    
    for(int n : numbers) {
        cout << n << " ";
    }
    cout << endl;
    return 0;
}

注意: std::vector には .pop_front() はありません。


2. 指定した位置の要素を削除する (.erase)

イテレータを使って、コンテナ内の特定の位置にある要素、または特定の範囲の要素を削除します。

サンプルコード

#include <iostream>
#include <vector>

using namespace std;

int main() {
    vector<int> numbers = {10, 20, 30, 40, 50};
    
    // 2番目の要素(30)を削除
    // .begin()は先頭を指すイテレータ
    numbers.erase(numbers.begin() + 2); // -> {10, 20, 40, 50}
    
    for(int n : numbers) {
        cout << n << " ";
    }
    cout << endl;
    return 0;
}

3. 条件に一致する要素を削除する

「偶数の要素を全て削除する」といった、特定の条件を満たす要素をまとめて削除するには、主に2つの方法があります。

方法A: Erase-Remove イディオム (C++17まで)

<algorithm>std::remove_if と、コンテナの .erase() を組み合わせる、伝統的な方法です。 remove_if は、削除すべきでない要素をコンテナの前方に詰め、実際に削除されるべき要素範囲の開始イテレータを返します。その後、.erase() でその範囲を物理的に削除します。

// ...
vector<int> data = {1, 2, 3, 4, 5, 6};

// remove_ifで偶数をコンテナの後方に移動させ、その開始地点を取得
auto first_to_erase = remove_if(data.begin(), data.end(), [](int n){ return n % 2 == 0; });

// その開始地点から末尾までをeraseで物理的に削除
data.erase(first_to_erase, data.end());

// data は {1, 3, 5} になる

方法B: std::erase_if (C++20以降)

C++20では、Erase-Removeイディオムの冗長さを解消する、よりシンプルで安全な std::erase_if が導入されました。

完成コード

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int main() {
    vector<int> numbers = {1, 2, 3, 4, 5, 6, 7, 8};
    
    // C++20の erase_if を使って、奇数の要素を全て削除
    erase_if(numbers, [](int n){ return n % 2 != 0; });
    
    for(int n : numbers) {
        cout << n << " ";
    }
    cout << endl;
    
    return 0;
}

解説: erase_if(コンテナ, 条件) という一行だけで、条件に一致する全ての要素が安全かつ効率的に削除されます。


4. mapsetからキーを指定して削除する

std::mapstd::setのような連想コンテナでは、キーを指定して .erase() を呼び出すことで、対応する要素を削除できます。

サンプルコード

#include <iostream>
#include <map>
#include <string>

using namespace std;

int main() {
    map<string, int> stock = {{"りんご", 5}, {"みかん", 8}, {"ぶどう", 3}};
    
    // キー "みかん" を持つ要素を削除
    stock.erase("みかん");
    
    for(const auto& [key, value] : stock) {
        cout << key << ": " << value << "個" << endl;
    }
    
    return 0;
}

まとめ

今回は、C++のコンテナから要素を削除する様々な方法を解説しました。

目的主な方法
先頭/末尾の削除.pop_front() / .pop_back()
位置を指定して削除.erase(イテレータ)
条件に合う要素を削除std::erase_if (C++20) / Erase-Removeイディオム
キーを指定して削除.erase(キー)

状況に応じて最適な削除方法を選択することが、効率的で読みやすいコードを書くための鍵となります。特に、条件に基づく削除では、C++20以降の環境であれば、std::erase_if を使うのが最もシンプルで安全です。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次