list

[C++] list::erase()の使い方 – 指定要素の削除

C++のstd::listクラスのerase()メソッドは、リストから指定した要素を削除するために使用されます。

引数としてイテレータを受け取り、削除した要素の次の要素を指すイテレータを返します。

範囲を指定して削除する場合は、開始イテレータと終了イテレータを渡します。

この場合、終了イテレータは削除対象に含まれません。

削除操作はリストの要素をシフトしないため効率的です。

list::erase()とは

C++の標準ライブラリに含まれるstd::listは、双方向リストを実装したコンテナです。

このコンテナは、要素の挿入や削除が効率的に行えるため、特に頻繁に要素を追加・削除する必要がある場合に適しています。

list::erase()は、std::listにおいて特定の要素を削除するためのメンバ関数です。

list::erase()を使用することで、リスト内の指定した位置にある要素を削除することができます。

この関数は、削除した要素の次の要素のイテレータを返すため、連続して要素を削除する際にも便利です。

以下に、list::erase()の基本的な使い方を示すサンプルコードを示します。

list::erase()の基本的な使い方

list::erase()を使用するには、まず削除したい要素の位置を示すイテレータを取得する必要があります。

std::listのイテレータを使って、削除したい要素を指定し、そのイテレータをerase()関数に渡します。

以下に基本的な使い方を示すサンプルコードを示します。

#include <iostream>
#include <list>
int main() {
    // std::listの作成
    std::list<int> myList = {1, 2, 3, 4, 5};
    // 削除したい要素のイテレータを取得
    std::list<int>::iterator it = myList.begin();
    std::advance(it, 2); // 3番目の要素(値は3)を指す
    // 要素の削除
    myList.erase(it); // 3を削除
    // 結果の表示
    for (int value : myList) {
        std::cout << value << " "; // 残った要素を表示
    }
    std::cout << std::endl; // 改行
    return 0;
}
1 2 4 5

このコードでは、std::listに整数を格納し、3番目の要素(値は3)を削除しています。

std::advance()を使用して、削除したい要素のイテレータを取得し、そのイテレータをerase()関数に渡すことで、指定した要素を削除しています。

削除後、残った要素を表示しています。

list::erase()の使用例

list::erase()の具体的な使用例をいくつか紹介します。

これにより、さまざまな状況でのerase()の使い方を理解できるでしょう。

以下の例では、特定の値を持つ要素を削除する方法や、範囲を指定して複数の要素を削除する方法を示します。

1. 特定の値を持つ要素の削除

以下のコードでは、リスト内の特定の値(例えば、値が2の要素)を削除します。

#include <iostream>
#include <list>
int main() {
    // std::listの作成
    std::list<int> myList = {1, 2, 3, 2, 4, 5};
    // 値が2の要素を削除
    myList.remove(2); // すべての2を削除
    // 結果の表示
    for (int value : myList) {
        std::cout << value << " "; // 残った要素を表示
    }
    std::cout << std::endl; // 改行
    return 0;
}
1 3 4 5

このコードでは、remove()メソッドを使用して、リスト内のすべての値が2の要素を削除しています。

erase()ではなくremove()を使用することで、特定の値を持つ要素を簡単に削除できます。

2. 範囲を指定して複数の要素を削除

次の例では、リストの一部の要素を範囲指定して削除します。

#include <iostream>
#include <list>
int main() {
    // std::listの作成
    std::list<int> myList = {1, 2, 3, 4, 5, 6, 7};
    // 3番目から5番目の要素を削除
    std::list<int>::iterator start = myList.begin();
    std::advance(start, 2); // 3を指す
    std::list<int>::iterator end = start;
    std::advance(end, 3); // 6を指す
    myList.erase(start, end); // 3, 4, 5を削除
    // 結果の表示
    for (int value : myList) {
        std::cout << value << " "; // 残った要素を表示
    }
    std::cout << std::endl; // 改行
    return 0;
}
1 2 6 7

このコードでは、erase()を使用して、3番目から5番目の要素(値は3, 4, 5)を削除しています。

startendのイテレータを指定することで、範囲を指定して複数の要素を一度に削除することができます。

これらの例を通じて、list::erase()の使い方や、他の削除方法との違いを理解することができます。

list::erase()の注意点

list::erase()を使用する際には、いくつかの注意点があります。

これらを理解しておくことで、意図しない動作を避け、効率的にプログラムを作成することができます。

以下に主な注意点を示します。

1. 削除後のイテレータの無効化

erase()を使用すると、削除した要素のイテレータは無効になります。

削除後にそのイテレータを使用すると、未定義の動作を引き起こす可能性があります。

削除後は、erase()が返すイテレータを使用することが推奨されます。

2. 複数の要素を削除する場合の注意

複数の要素を削除する際、範囲を指定してerase()を使用することができますが、範囲の指定が正確でないと、意図しない要素が削除されることがあります。

範囲の開始と終了のイテレータを正しく設定することが重要です。

3. リストのサイズの変化

要素を削除すると、リストのサイズが変化します。

特に、ループ内で要素を削除する場合、ループの条件やインデックスに影響を与える可能性があるため、注意が必要です。

ループの中で要素を削除する場合は、イテレータを適切に管理する必要があります。

4. 削除する要素が存在しない場合

erase()を使用して削除しようとした要素がリストに存在しない場合、特にエラーは発生しませんが、何も削除されないことになります。

削除の結果を確認するために、削除前後のリストの状態を確認することが推奨されます。

5. 例外安全性

list::erase()は、通常、例外を投げることはありませんが、リストの要素がポインタや参照を持つ場合、削除後にそれらのポインタや参照が無効になる可能性があります。

これにより、プログラムがクラッシュすることがあるため、注意が必要です。

これらの注意点を理解し、適切にlist::erase()を使用することで、より安全で効率的なプログラムを作成することができます。

list::erase()と他の削除方法の比較

C++のstd::listには、要素を削除するためのいくつかの方法があります。

ここでは、list::erase()と他の削除方法remove()clear()を比較し、それぞれの特徴を理解します。

以下の表に、各削除方法の違いをまとめました。

削除方法説明使用例
erase()指定した位置の要素を削除する。myList.erase(it);
remove()指定した値を持つすべての要素を削除する。myList.remove(value);
clear()リスト内のすべての要素を削除する。myList.clear();

1. list::erase()

list::erase()は、指定したイテレータが指す要素を削除します。

特定の位置にある要素を削除したい場合に便利です。

また、範囲を指定して複数の要素を削除することもできます。

削除後は、削除した要素の次の要素を指すイテレータが返されます。

2. remove()

remove()は、リスト内のすべての要素の中から、指定した値を持つ要素を削除します。

このメソッドは、リストの要素を直接操作するのではなく、リストの内容を変更するために新しいリストを作成し、元のリストを更新します。

したがって、remove()は、特定の値を持つ要素を一度に削除したい場合に便利です。

3. clear()

clear()は、リスト内のすべての要素を削除します。

このメソッドを使用すると、リストを空にすることができます。

リストのサイズが大きい場合や、すべての要素を一度に削除したい場合に適しています。

clear()を使用すると、リストは空になりますが、リスト自体は残ります。

  • list::erase()は、特定の位置や範囲の要素を削除するのに適しています。
  • remove()は、特定の値を持つすべての要素を削除するのに便利です。
  • clear()は、リスト内のすべての要素を一度に削除するために使用します。

これらの削除方法を使い分けることで、std::listをより効果的に操作することができます。

状況に応じて適切な方法を選択することが重要です。

応用的な使い方

list::erase()は、基本的な使い方だけでなく、さまざまな応用的なシナリオでも活用できます。

ここでは、いくつかの応用的な使い方を紹介します。

1. 条件に基づく要素の削除

特定の条件に基づいて要素を削除する場合、イテレータを使ってリストを走査し、条件に合致する要素を削除することができます。

以下の例では、偶数の要素を削除します。

#include <iostream>
#include <list>
int main() {
    // std::listの作成
    std::list<int> myList = {1, 2, 3, 4, 5, 6, 7, 8, 9};
    // 偶数の要素を削除
    for (auto it = myList.begin(); it != myList.end(); ) {
        if (*it % 2 == 0) { // 偶数の場合
            it = myList.erase(it); // 削除し、次の要素のイテレータを取得
        } else {
            ++it; // 次の要素へ
        }
    }
    // 結果の表示
    for (int value : myList) {
        std::cout << value << " "; // 残った要素を表示
    }
    std::cout << std::endl; // 改行
    return 0;
}
1 3 5 7 9

このコードでは、リスト内の偶数の要素を削除しています。

イテレータを使ってリストを走査し、条件に合致する要素を削除することで、柔軟な操作が可能です。

2. 複数の要素を一度に削除

特定の範囲の要素を一度に削除する場合、erase()を使って範囲を指定することができます。

以下の例では、3番目から5番目の要素を削除します。

#include <iostream>
#include <list>
int main() {
    // std::listの作成
    std::list<int> myList = {1, 2, 3, 4, 5, 6, 7, 8, 9};
    // 3番目から5番目の要素を削除
    auto start = myList.begin();
    std::advance(start, 2); // 3を指す
    auto end = start;
    std::advance(end, 3); // 6を指す
    myList.erase(start, end); // 3, 4, 5を削除
    // 結果の表示
    for (int value : myList) {
        std::cout << value << " "; // 残った要素を表示
    }
    std::cout << std::endl; // 改行
    return 0;
}
1 2 6 7 8 9

このコードでは、erase()を使用して、3番目から5番目の要素を一度に削除しています。

範囲を指定することで、複数の要素を効率的に削除できます。

3. リストの逆順での削除

リストを逆順で走査しながら要素を削除することも可能です。

逆順で走査することで、削除によるイテレータの無効化を避けることができます。

以下の例では、リストの要素を逆順で表示し、特定の条件に合致する要素を削除します。

#include <iostream>
#include <list>
int main() {
    // std::listの作成
    std::list<int> myList = {1, 2, 3, 4, 5, 6, 7, 8, 9};
    // 逆順で走査し、偶数の要素を削除
    for (auto it = myList.end(); it != myList.begin(); ) {
        --it; // 逆順に移動
        if (*it % 2 == 0) { // 偶数の場合
            myList.erase(it); // 削除
        }
    }
    // 結果の表示
    for (int value : myList) {
        std::cout << value << " "; // 残った要素を表示
    }
    std::cout << std::endl; // 改行
    return 0;
}
1 3 5 7 9

このコードでは、リストを逆順で走査し、偶数の要素を削除しています。

逆順での走査は、削除によるイテレータの無効化を避けるための有効な手段です。

これらの応用的な使い方を通じて、list::erase()の柔軟性と強力さを理解し、さまざまなシナリオで活用できるようになります。

まとめ

この記事では、C++のlist::erase()の使い方やその応用について詳しく解説しました。

特定の要素を削除する基本的な方法から、条件に基づく削除や範囲指定での削除、逆順での削除まで、さまざまなシナリオでの活用方法を紹介しました。

これらの知識を活かして、実際のプログラムにおいてリスト操作をより効率的に行うことを目指してください。

関連記事

Back to top button