使用find_if清除向量中的所有偶数

时间:2017-12-14 16:45:28

标签: c++ stl

#include <iostream>
#include <vector>
#include <algorithm>
#include <time.h>
#include <iomanip>

using namespace std;

bool isEven(int n)
{ 
    return n%2 == 0;
}

int main()
{
    srand(time(NULL));

    vector<int> myVec;

    for(int i = 0; i < 20; i++)
    {
        myVec.push_back(rand() % 100);
    }   
    while(1)
    {   
          vector<int>::iterator q = std::find_if(myVec.begin(), myVec.end(), isEven);
          cout << *q << endl;
          if(q == myVec.end())
          {   
             myVec.erase(q);
             break;
          }   
          else
             myVec.erase(q);        
      }

    return 0;
}

此代码给出了分段错误。上面的代码是使用find_if和erase函数

从向量中删除所有偶数

请帮忙。任何帮助将受到高度赞赏。

编辑:我编辑了它以确保迭代器始终有效。

仍然是分段错误。

2 个答案:

答案 0 :(得分:5)

std::vector::erase使擦除点之前和之后的所有迭代器无效。您不能继续使用该迭代器,不能递增它,使用它来访问矢量,甚至将它与end()进行比较。

使用的正确算法是std:remove_if。与名称不同,它只会将向量的所有偶数项“移动到后面”,而不会使任何迭代器无效。它会将迭代器返回到此子范围的开头,然后您可以将其提供给相应的erase重载(接受一对迭代器的重载)。

这在代码中被广泛使用,甚至被称为“擦除删除习语”。

答案 1 :(得分:1)

使用erase(it);函数时,迭代器会发生变化,因此您需要再次将迭代器设置为擦除函数返回的新迭代器。

在您的代码中,您正在检查结束if(q == myVec.end()),然后使用擦除这将抛出错误as.end()不指向数据,并且能够从向量中擦除项目迭代器需要有效。因此,通过将if(q == myVec.end())更改为if(q == (myVec.end()-1)),它将允许您删除最后一个元素,如果是一对。