2

コンテナーから値の範囲を消去する関数を実装することになっています。そう

eraseRange(v, 1.5, 24);

たとえば、コンテナ v から 1.5 より大きく 24 より小さい値を削除します。そして、私の関数はリストに対して完全に機能します。

container.erase(remove_if(container.begin(), container.end(), rg));

rg は範囲内にあるかどうかをチェックします (その部分の実装は問題ではないので、詳しくは説明しません)。

ただし、ベクトルに対して eraseRange を呼び出し、同様のメソッドを使用して値を消去すると、最初の値のみが消去されます。したがって、1 から 10 までの数字を持つベクトルを使用する場合、次のように呼び出します。

eraseRange(v, 3, 7);

削除されるのは 3 つだけです。

通常、これは問題になりません。イテレータを使用して値を確認するだけです。この特定の演習を除いて、for/while/do ループは明示的に禁止されています...

したがって、問題はランダム アクセス イテレータを持つコンテナーにあるようです。そして、代替手段として何を実装すればよいかわかりません。ヘルプ?

4

2 に答える 2

11

のオーバーロードがいくつかありeraseます。

使用している 1 つのオーバーロードは、1 つの反復子を取り、反復子が指す要素を消去します。

使用する必要があるもう 1 つのオーバーロードは、範囲 (反復子のペア) を取り、範囲内のすべての要素を消去します。

c.erase(remove_if(c.begin(), c.end(), rg), c.end());
                                         ^^^^^^^^^

[あなたが言うように、あなたのコードが「リストに対して完全に機能する」理由がわかりません。std::listの同じ 2 つのオーバーロードがありeraseます。には特に最適化された消去/削除アルゴリズムのより良い実装を提供するstd::listメンバー関数 もあることに注意してください(はリンクされたリストとして実装されているため、実際にオブジェクトを移動せずに消去/削除を実装できます)。remove_ifstd::liststd::list

于 2011-10-11T17:36:28.927 に答える
2

remove_if単一のイテレータを「new last」に返します。それは、述語を満たすすべてをシャッフルして、ベクトル内の過去の新しいものまでです。new last より前のすべては述語を満たしませんが、それ以降はすべて満たします。ベクターから単一のアイテムに対してのみ消去を実行しているため、新しい最後のみを削除しています。これは、述語を満たす唯一のものです。代わりに、述語を満たすすべてのものである new last -> end からすべてを消去したい

container.erase(
   remove_if(container.begin(), container.end(), rg), 
   container.end()
 );
于 2011-10-11T17:38:28.647 に答える