【问题标题】:vector.erase and std::remove on custom vector自定义向量上的 vector.erase 和 std::remove
【发布时间】:2016-01-26 14:13:41
【问题描述】:

我有一个整数对向量。假设 Itr 作为这个向量的迭代器。 我想遍历向量并决定是否从向量中删除元素。如果向量的元素是9001,3,那么我想从向量中删除所有itr->first 为9001 的元素(不管itr->second 是什么)。

问题:

  1. 如何删除这个整数对向量。以下方法不起作用: vec.erase(std::remove(vec.begin(), vec.end(), Itr->first=9001), vec.end());
  2. 我可以不给 vec.begin() 给 vec.end() 的范围 vec.begin 为 (current element being pointer by vector) - 10 和 ve.end 为(current element being pointed by vector)+10

例如:vec.erase(std::remove(Itr-10, Itr+10, Itr->first=9001), vec.end());

如果向量大小本身小于10,Itr+10 ot Itr-10 可能会导致分段错误。那么如何处理这种情况呢?

    vector<pair<int,int> > vec;

    vec.push_back(pair<int,int>(9001,1));
    vec.push_back(pair<int,int>(9001,2));
    vec.push_back(pair<int,int>(9001,3));
    vec.push_back(pair<int,int>(9001,4));
    vec.push_back(pair<int,int>(9002,1));
    vec.push_back(pair<int,int>(9002,2));
    vec.push_back(pair<int,int>(9002,3));
    vec.push_back(pair<int,int>(9002,4));
    vec.push_back(pair<int,int>(9002,5));


    vector<pair<int,int> >::iterator Itr;
    for(Itr=vec.begin();Itr!=vec.end();++Itr)
            cout<<vecItr->first<<" "<<vecItr->second;

//  vec.erase(std::remove(Itr-10, Itr+10, Itr->first=9001), vec.end()); //This doest work

    for(Itr=vec.begin();Itr!=vec.end();++Itr)
            cout<<Itr->first<<" "<<Itr->second;

【问题讨论】:

标签: c++ vector stl


【解决方案1】:

如何删除这个 int 对向量。以下方法不起作用:

将 lambda 或自定义比较器与 remove_if 算法一起使用:

vec.erase(std::remove_if(vec.begin(), vec.end(), 
                         [](auto& elem){ return elem.first == 9001;} ),
          vec.end());

使用自定义比较器:

struct elem_equals
{
    typedef std::pair<int,int> elem_t
    const int value;

    elem_equals(int v) : value(v) {}

    bool operator()(elem_t& elem) 
    {
        return elem.first == value;
    }
};

//...

vec.erase(std::remove_if(vec.begin(), vec.end(), 
                         elem_equals(9001) ),
          vec.end());

我是否可以将 vec.begin 作为 (current element being pointer by vector) - 10ve.end as (current element being pointed by vector)+10 来代替 vec.begin() 到 vec.end() 的范围?

是的。向量迭代器支持指针运算,所以很简单。

如果向量大小本身小于10,Itr+10 ot Itr-10 可能会导致分段错误。那么如何处理这种情况呢?

如果在迭代器之前或之后没有足够的元素,则限制你的范围:

//iter is an iterator to vector
//vec is instance of std::vector
//replace auto with std::vector<std::pair<int,int> >::iterator for non C++11 compilers
auto begin = iter - std::min(10, iter - vec.begin());
auto end = iter + std::min(10, vec.end() - iter);

【讨论】:

  • lambda 接收的不是迭代器,而是一个实际的元素。在 lambda 参数中使用 auto 是 c++14。
  • @stefaanv 谢谢,已修复。至于 C++14,没有要求不使用它。但无论如何我都会改变它。
  • 不幸的是,我不在 C++11 或更高版本上使用 lambda。我还有其他选择吗?
  • @anurag86 ,当然,自定义比较器。我将立即编辑我的答案并添加示例
  • 我并不是说你不应该使用 C++14,我只是指出那些尝试你的例子的人。可能与 1 中的 2 条评论有点混淆。
猜你喜欢
  • 2013-09-19
  • 1970-01-01
  • 2013-10-18
  • 2014-07-08
  • 2012-12-04
  • 1970-01-01
  • 2021-03-03
  • 2018-02-14
  • 1970-01-01
相关资源
最近更新 更多