13

std::vectorから目的の項目を完全に削除する良い方法は、erase-remove というイディオムであると一般に理解されています。

上記のリンクに記載されているように (この投稿の日付の時点で)、コードでは、消去と削除のイディオムは次のようになります。

int main()
{
  // initialises a vector that holds the numbers from 0-9.
  std::vector<int> v = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

  // erase-remove idiom to completely eliminate the desired items from the vector
  v.erase( std::remove( std::begin(v), std::end(v), 5 ), std::end(v) ); 
}

resize-removeイディオムが機能とパフォーマンスの点でイディオムと同等かどうかを知りたいerase-removeです。または、おそらく私は明らかな何かを見逃していますか?

次のresize-removeイディオムは上記のイディオムと同等erase-removeですか?

int main()
{
  std::vector<int> v = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

  // Is this "resize-remove" approach equivalent to the "erase-remove" idiom?
  v.resize( std::remove( std::begin(v), std::end(v), 5 ) - v.begin() ); 
}
4

4 に答える 4

11

私の意見では、2 つの理由があります。

  1. std::removealgorithm には Forward Iterator のみが必要ですが、-op には Random Access Iterator が必要です。

  2. の結果は、std::remove「コンテナの新しい終わり」を意味します。論理的には、[「コンテナーの新しい終わり」、「コンテナーの古い終わり」) を消去する必要があります。

于 2014-04-04T10:41:52.107 に答える
6

std::vector では同等ですが、std::list やその他のコンテナーでは同等ではありません。std::list でイテレータの減算が可能かどうかはわかりません。可能であっても、それは O(N) 操作です。

于 2014-04-04T10:43:03.683 に答える
1

以前の要素がアクセスまたは変更されないことeraseを保証すると思いますが、サイズ変更のために再割り当てが発生しない場合にのみこれを保証します。erase(first,last)firstresize

編集:他の人が指摘したように、そのような再割り当ては決して起こらないので、違いはありません

于 2014-04-04T10:34:08.313 に答える