remove_if删除vector中的数据

Remove_if的等效操作

 

template < class ForwardIterator, class Predicate >
  ForwardIterator remove_if ( ForwardIterator first, ForwardIterator last,
                              Predicate pred )
{
  ForwardIterator result = first;
  for ( ; first != last; ++first)
    if (!pred(*first)) *result++ = *first;
  return result;
}

 

删除vector中的数据

vector能够非常容易地添加数据,也能很方便地取出数据,同样vector提供了erase()pop_back()clear()来删除数据,当你删除数据的时候,你应该知道要删除尾部的数据,或者是删除所有数据,还是个别的数据。在考虑删除等操作之前让我们静下来考虑一下在STL中的一些应用。

 

Remove_if()算法

现在我们考虑操作里面的数据。如果要使用remove_if(),我们需要在头文件中包含如下代码::

 

#include <algorithm>

 

Remove_if()有三个参数:

1、   iterator _First:指向第一个数据的迭代指针。

2、   iterator _Last:指向最后一个数据的迭代指针。

3、   predicate _Pred:一个可以对迭代操作的条件函数。

 

条件函数

条件函数是一个按照用户定义的条件返回是或否的结果,是最基本的函数指针,或者是一个函数对象。这个函数对象需要支持所有的函数调用操作,重载operator()()操作。remove_if()是通过unary_function继承下来的,允许传递数据作为条件。

例如,假如你想从一个vector<CString>中删除匹配的数据,如果字串中包含了一个值,从这个值开始,从这个值结束。首先你应该建立一个数据结构来包含这些数据,类似代码如下:

 

#include <functional>
enum findmodes
{
 FM_INVALID = 0,
 FM_IS,
 FM_STARTSWITH,
 FM_ENDSWITH,
 FM_CONTAINS
};
typedefstruct tagFindStr
{
 UINT iMode;
 CString szMatchStr;
} FindStr;
typedef FindStr* LPFINDSTR;

 

然后处理条件判断:

 

class FindMatchingString
    : public std::unary_function<CString, bool>
{
   
public:
  FindMatchingString(const LPFINDSTR lpFS) : m_lpFS(lpFS) {}
   
  bool operator()(CString& szStringToCompare) const
  {
     bool retVal = false;
 
     switch(m_lpFS->iMode)
     {
     case FM_IS:
       {
         retVal = (szStringToCompare == m_lpFDD->szMatchStr);
         break;
       }
     case FM_STARTSWITH:
       {
         retVal = (szStringToCompare.Left(m_lpFDD->szMatchStr.GetLength())
               == m_lpFDD->szWindowTitle);
         break;
       }
     case FM_ENDSWITH:
       {
         retVal = (szStringToCompare.Right(m_lpFDD->szMatchStr.GetLength())
               == m_lpFDD->szMatchStr);
         break;
       }
     case FM_CONTAINS:
       {
         retVal = (szStringToCompare.Find(m_lpFDD->szMatchStr) != -1);
         break;
       }
     }
       
     return retVal;
 }
       
private:
    LPFINDSTR m_lpFS;
};

 

通过这个操作你可以从vector中有效地删除数据:

 

// remove all strings containing the value of
// szRemove from vector<CString> vs.
 
FindStr fs;
fs.iMode = FM_CONTAINS;
fs.szMatchStr = szRemove;
 
vs.erase(std::remove_if(vs.begin(), vs.end(), FindMatchingString(&fs)), vs.end());

 

Remove_if()能做什么?

你可能会疑惑,对于上面那个例子在调用remove_if()的时候还要使用erase()呢?这是因为大家并不熟悉STL中的算法。Remove(),remove_if()等所有的移出操作都是建立在一个迭代范围上的,那么不能操作容器中的数据。所以在使用remove_if(),实际上操作的时容器里数据的上面的。思考上面的例子:

1、   szRemove = “o”.

2、   vs见下面图表中的显示。

 

观察这个结果,我们可以看到remove_if()实际上是根据条件对迭代地址进行了修改,在数据的后面存在一些残余的数据,那些需要删除的数据。剩下的数据的位置可能不是原来的数据,但他们是不知道的。

调用erase()来删除那些残余的数据。注意上面例子中通过erase()删除remove_if()的结果和vs.enc()范围的数据。

 

C++的STL通过iterator将container和algorithm分离,并通过functor提供高可定制性。

一种删除元素方式,虽然不用迭代器,但是感觉也还是不错地,记一下。

 

std::vector<int> a;
for (size_t i = 0; i < a.size(); )
{
if (a[i] == 5)
{
a.erase(a.begin() + i);
}
else
{
i++;
}
}

 

 

 

 

 

 

 

 

 

转载于:https://www.cnblogs.com/LOB104-zhanglei/articles/3491653.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
`remove_if` 是 C++ 标准库的一个算法,它属于 `<algorithm>` 头文件的一部分。这个函数用于从给定的范围(如容器、数组等)移除所有满足特定条件的元素。它接受两个参数:一个是待操作的范围的迭代器,另一个是一个谓词(predicate),即一个函数对象或函数指针,该函数会根据某个标准判断一个元素是否需要被移除。 例如,假设我们有一个整数向量 `v`,我们可以使用 `std::remove_if(v.begin(), v.end(), std::predicates::equal(0))` 来移除所有值为 0 的元素。这里,`std::predicates::equal(0)` 就是谓词,如果元素等于 0,则会被移除。 错误分析: 1. 如果没有包含 `<algorithm>` 头文件,函数调用会报错。 2. 如果谓词不是一个有效的函数对象或函数指针,可能会导致类型不匹配错误。 3. 输入的迭代器可能无效,比如指向了超出范围的位置,这可能导致未定义的行为。 4. 当处理大量数据时,如果没有足够的内存来存储删除后的元素,可能导致栈溢出或程序崩溃。 修复后的代码示例: ```cpp #include <iostream> #include <vector> #include <algorithm> // 假设我们有一个整数向量和一个谓词函数 std::vector<int> v = {0, 1, 2, 3, 4, 0, 5}; // 定义一个谓词函数,检查元素是否等于 0 bool is_zero(int n) { return n == 0; } // 使用 remove_if 清理 0 元素 void remove_zeros(std::vector<int>& vec) { vec.erase(std::remove_if(vec.begin(), vec.end(), is_zero), vec.end()); } int main() { remove_zeros(v); for (const auto& num : v) { std::cout << num << " "; } return 0; } ``` 这段代码首先包含了必要的头文件,然后定义了一个检查元素是否为 0 的谓词函数 `is_zero`。在 `main()` 函数,通过调用 `remove_zeros` 函数并传入向量 `v`,将其的 0 删除后输出剩余的元素。这样就修复了可能存在的错误。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值