1

C ++で値によって要素を削除するという質問に対するこの回答に出くわしました:

C ++位置ではなく値でベクトル要素を消去しますか?

基本的:

vec.erase(std::remove(vec.begin(), vec.end(), valueToRemove), vec.end());

答えは一理ありますが、これはスタイルが悪いのではないですか?ロジックは二重否定で構成されています...これを行うためのよりクリーンな方法はありますか?

4

3 に答える 3

6

コレクションからの要素の削除は、次の 2 つの手順で構成されます。

  • 一致によって作成された穴を埋めるために、後続のすべての要素を下に移動します
  • 新たな終焉を告げる

C++ 標準ライブラリでは、これらはそれぞれremoveとの 2 つの別個の関数eraseです。

確かに、より使いやすい関数のタイプを想像することはできerase_ifますが、明らかに現在のコードで十分であると考えられています。もちろん、自分で書くこともできますremove_if

于 2011-09-05T16:08:19.833 に答える
4

これは悪くなく、実際、線形時間の条件に基づいてベクトルから要素を削除する効率的な方法です。この動画の 35 分からご覧ください。Erase and Remove Idiom の STL の説明

于 2011-09-05T16:07:59.497 に答える
1

コンテナーにはさまざまな種類があることに注意してください: 連続 vs ノードベース、順次 vs 連想。

ノードベースのコンテナーにより、効率的な消去/挿入が可能になります。シーケンシャル コンテナは要素を挿入順序 (つまり位置) で編成しますが、連想コンテナは要素を (キー) 値で編成します。

現在のすべての連想コンテナー (マップ/セット/順序なし) はノードベースであり、それらを使用して要素を直接消去でき、要素ごとのメンバーerase関数を直接使用する必要があります。リストはノードベースのシーケンス コンテナーであるため、個々の要素を効率的に消去できますが、値による要素の検索には直線的な時間がかかります。これが、リストがメンバーremove関数を提供する理由です。値によって要素を消去する簡単な方法がないのは、シーケンス コンテナー (ベクターおよびデキュー) だけです。 そこで、フリーremoveアルゴリズムが登場します。このアルゴリズムは、最初にシーケンスを再配置eraseし、コンテナーのメンバーがコンテナーの最後で効率的な消去を実行できるようにします。

基礎となるコンテナの知識がなくても機能する標準ライブラリの多くの一般的な側面とは異なり、コピー/消去のイディオムは、コンテナ間の違いについて少し詳細な知識を必要とするものの 1 つです。

于 2011-09-05T16:17:25.573 に答える