c++学習の容器——erase()関数
1801 ワード
まずerase()関数の使い方を紹介し、erase()関数は順序型容器から容器の1つの要素を削除するために使用され、2つの関数プロトタイプ、c.erase(p)、c.erase(b,e)がある.1番目の削除反復器pが指す要素、2番目の削除反復器b,eがマークする範囲内の要素、cはコンテナオブジェクトであり、戻り値はすべて削除された要素の後ろの要素(これがポイント)を指す反復器であり、具体的な詳細は他の資料を参照してください.
「c++primer」の練習問題9.26のような問題があります.この問題は以下のように要求されています.
配列int a[]={0,1,2,3,5,8,13,21,55,89}がある.配列をvectorコンテナとlistコンテナに保存し、vectorコンテナの偶数を削除し、listコンテナの奇数を削除する必要があります.
これはコアアルゴリズムコードにすぎず、基本的には考慮すべき問題を考慮しています.例えば、要素を削除した後、ポインタはその削除要素の後ろの要素を指します.ループに1を追加すると、削除された要素の次の要素をスキップしますが、深刻な問題があります.Vertorセグメントのコードを見てみましょう.
次に、最初のデータを例にとると、最初の要素0を削除した後、戻ったiterが次の要素1を指し、自己減算演算を行うと、問題が発生し、前の要素0が削除され、このとき自己減算演算で得られた結果が野ポインタであり、シーケンスに問題が発生する.つまり、上記のコード形式は異なるデータの順序に対して異なる結果を生み出し、エラーが発生する可能性があります.これは明らかに私たちが望んでいないことです.コードを次の形式に変更しました.
このような形式では、データの順序は結果に影響しないし、野ポインタの問題も起こらないし、2番目のerase()関数を考えると、erase()関数の使い方にはあまり制限がないと思います.容器操作、容器内の要素の削除、erase関数の使用には、常に覚えておく必要がある2つの点があります.
1つ目はerase関数の戻り値であり、削除された要素の次の要素を指す反復器です.
2つ目は、erase関数を使用した後の反復器が野ポインタを生成するかどうかです.これでコードを書くときに大きな問題は発生しません.
この文章を書くのは主にネット上の容器に関するerase()関数の紹介が詳しくないことを発見して、もし何か問題があれば、批判の指摘を歓迎します.
「c++primer」の練習問題9.26のような問題があります.この問題は以下のように要求されています.
配列int a[]={0,1,2,3,5,8,13,21,55,89}がある.配列をvectorコンテナとlistコンテナに保存し、vectorコンテナの偶数を削除し、listコンテナの奇数を削除する必要があります.
for(list::iterator iter = ilst.begin();
iter != ilst.end();iter++
){
if((*iter) %2 == 1){
// int tmp = *iter;
iter = ilst.erase(iter);
--iter;
// continue;
}
// iter++;
}
これはコアアルゴリズムコードにすぎず、基本的には考慮すべき問題を考慮しています.例えば、要素を削除した後、ポインタはその削除要素の後ろの要素を指します.ループに1を追加すると、削除された要素の次の要素をスキップしますが、深刻な問題があります.Vertorセグメントのコードを見てみましょう.
for(vector::iterator iter = ivec.begin();
iter != ivec.end(); iter++
){
if((*iter) %2 == 0){
// int tmp = *iter;
iter = ivec.erase(iter);
--iter;
// continue;
}
// iter++;
}
次に、最初のデータを例にとると、最初の要素0を削除した後、戻ったiterが次の要素1を指し、自己減算演算を行うと、問題が発生し、前の要素0が削除され、このとき自己減算演算で得られた結果が野ポインタであり、シーケンスに問題が発生する.つまり、上記のコード形式は異なるデータの順序に対して異なる結果を生み出し、エラーが発生する可能性があります.これは明らかに私たちが望んでいないことです.コードを次の形式に変更しました.
for(vector::iterator iter = ivec.begin();
iter != ivec.end(); //iter++
){
if((*iter) %2 == 0){
// int tmp = *iter;
iter = ivec.erase(iter);
// --iter;
continue;
}
iter++;
}
このような形式では、データの順序は結果に影響しないし、野ポインタの問題も起こらないし、2番目のerase()関数を考えると、erase()関数の使い方にはあまり制限がないと思います.容器操作、容器内の要素の削除、erase関数の使用には、常に覚えておく必要がある2つの点があります.
1つ目はerase関数の戻り値であり、削除された要素の次の要素を指す反復器です.
2つ目は、erase関数を使用した後の反復器が野ポインタを生成するかどうかです.これでコードを書くときに大きな問題は発生しません.
この文章を書くのは主にネット上の容器に関するerase()関数の紹介が詳しくないことを発見して、もし何か問題があれば、批判の指摘を歓迎します.