「労働者が自分の仕事をうまくやりたいなら、まず自分の道具を研ぎ澄まさなければなりません。」 - 孔子、「論語。陸霊公」
表紙 > プログラミング > `std::vector` から要素を削除するときに、erase-remove_if が重複したペアを残すのはなぜですか?

`std::vector` から要素を削除するときに、erase-remove_if が重複したペアを残すのはなぜですか?

2024 年 12 月 23 日に公開
ブラウズ:919

Why does erase-remove_if leave behind duplicate pairs when removing elements from a `std::vector`?

ペア削除の Erase-Remove_if イディオム

erase-remove_if イディオムを使用して std::vector> では、特有の問題が発生します。 .first 値が 4 のペアを削除のターゲットにしているにもかかわらず、最初の実装では重複したペアが残されます:

stopPoints.erase(std::remove_if(stopPoints.begin(),
                                stopPoints.end(),
                                [&](const stopPointPair stopPoint)-> bool { return stopPoint.first == 4; }));

問題の根本は、不完全な消去プロセスにあります。 std::erase_if は、一致する要素をベクトルの末尾に移動するだけです。それらは削除されません。削除を完了するには、std::remove_if によって返される反復子を消去の開始点として使用するのが正しいアプローチです:

stopPoints.erase(std::remove_if(stopPoints.begin(),
                                stopPoints.end(),
                                [](const stopPointPair stopPoint)-> bool 
                                       { return stopPoint.first == 4; }), 
                 stopPoints.end());

Erase-Remove_if メカニズムの理解:

  • 要素の交換: std::remove_if は要素を交換しますベクトル内で、一致しないすべての要素を先頭の方に押し込みます。一致した要素はベクトルの後部に配置されます。
  • Predicate Iteration: 述語ラムダ式は、どの要素を削除するかを決定します。述語が true を返す場合、対応する要素はベクトルの末尾に移動されます。
  • Iterator Retrieval: std::remove_if は、述語に一致する最初の要素を指す反復子を返します。この反復子は、削除される要素の開始をマークします。
  • Vector Erasure: std::vector::erase は、返された反復子から開始してベクトルの範囲まで拡張する範囲消去操作を呼び出します。終わり。このステップでは、一致したすべての要素をベクターから削除します。

さらに詳しい洞察については、[Erase-Remove Idiom](https://en.wikipedia.org/) に関するウィキペディアの記事を参照してください。 wiki/Erase-remove_idiom).

最新のチュートリアル もっと>

免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。

Copyright© 2022 湘ICP备2022001581号-3