Erase-remove 慣用法

        從一個向量中刪除一個符合特定規則的元素用到了,如下的句式:

<span style="font-size:18px;">     vec.erase( 
               std::remove_if(vec.begin(),vec.end(),RemovePred), 
               vec.end() 
               );</span>
        erase的這種用法是刪除一個區間的元素,但現在要刪除的是分佈在vec中各處的,百思不得其解。

        經查找,在維基百科上找到了答案,翻譯如下:


        一個編程的常見工作就是在容器中刪除所有擁有特定值或者符合特定標準的元素。在C++ 中,可以用循環自己實現,但更推薦的做法是用C++標準庫來完成。

        對此,算法庫中提供了romove 和remove_if 算法。因爲這些算法在預先給的兩個指針上操作,它們並沒有容器或集合上的信息。所以,並沒有元素被實際刪除,而是,所有不符合規則的元素被移動到了序列的開頭。相對來說,剩下的元素就是有效的了。但未特別指明的是,在這完成後,remove 算法返回了指向最後一個未被刪除的元素的下一個位置的迭代器。

        爲了實際清除容器中的元素,remove 結合了容器的erase方法,因此稱爲 ” erase-remove慣用法 "。

        附上維基百科上的代碼備忘。

<span style="font-size:14px;">// Use g++ -std=c++11 or clang++ -std=c++11 to compile.
 
#include <vector> // the general-purpose vector container
#include <iostream>
#include <algorithm> // remove and remove_if
 
bool is_odd(int i)
{
  return (i % 2) != 0;  
}
 
void print(const std::vector<int> &vec)
{
  for (const auto& i: vec) 
    std::cout << i << ' '; 
  std::cout << std::endl;
}
 
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 };
  print(v);
 
  // removes all elements with the value 5
  v.erase( std::remove( std::begin(v), std::end(v), 5 ), std::end(v) ); 
  print(v); 
 
  // removes all odd numbers
  v.erase( std::remove_if(std::begin(v), std::end(v), is_odd), std::end(v) );
  print(v);
 
  return 0;  
}
 
/*
Output:
0 1 2 3 4 5 6 7 8 9 
0 1 2 3 4 6 7 8 9 
0 2 4 6 8 
*/
</span>



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章