【问题标题】:Remove vector elements based on the index根据索引移除向量元素
【发布时间】:2012-01-15 16:40:32
【问题描述】:

我想根据索引删除向量的元素,比如所有偶数索引元素。 我已阅读有关擦除删除习语的信息,但看不到如何应用它。 这是我尝试过的:

    vector<int> line;
    line.reserve(10);
    for(int i=0;i<10;++i)
    {
      line.push_back(i+1);
    }
    for(unsigned int i=0;i<line.size();++i)
    {
      //remove the even indexed elements
      if(i%2 == 0)
      {
        remove(line.begin(),line.end(),line[i]);
      }
    }
line.erase( line.begin(),line.end() );

这会擦除整个向量。我希望只删除已被删除算法标记的元素。

然后我尝试了这个

for(unsigned int i=0;i<line.size();++i)
    {
      //remove the even indexed elements
      if(i%2 == 0)
      {
        line.erase( remove(line.begin(),line.end(),line[i]),line.end() );
      }
    }

这再次不起作用,因为删除时出现问题,索引似乎在迭代向量时发生了变化。 完成此任务的正确方法应该是什么。

【问题讨论】:

    标签: c++ stl vector erase-remove-idiom


    【解决方案1】:

    通过从0size,您最终会跳过一半的元素,因为索引会随着您擦除元素而改变。让您的for 循环从size() 变为0

    for(unsigned int i = line.size(); i > 0; i--)
    {
    
    }
    

    【讨论】:

    • 我希望你的意思是size() - 1
    • 没有。如果 size == 0,那会弄乱循环。每当您引用元素时,只需转到 [i-1]
    • for(std::vector&lt;int&gt;::iterator it = line.end(); it != line.begin(); --it)?
    • @AusCBloke 没有。它是unsigned int,这意味着i 实际上会大于0,即使它是-1==0xFFFFFFFF=4294967295,你也会进入一个近乎无限的循环。
    • @JosephH:哈哈,糟糕,没有注册unsigned 部分,只看到了int。为此 +1。
    【解决方案2】:

    Online Demo

    #include <vector> 
    #include <algorithm>
    #include <iostream>
    
    /*Check if Index is Even or Odd*/ 
    bool is_IndexEven(int i) 
    {
       static int k = 1;
    
       /*Handle Index 0 as special case as per choice*/
       if(k == 1)
       {
           k++;
           return false;
       } 
    
       if(k++ % 2)
           return true;
       else 
           return false; 
     }
    
    int main() 
    {
        using namespace std;
        int elements[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    
        // create a vector that holds the numbers from 0-9.
        vector<int> v(elements, elements + 10); 
    
        /*Display elements before removal*/    
        vector<int>::const_iterator iter = v.begin();
        cout<<"Before\n";
    
        for(iter;iter!= v.end();++iter)
        {
            cout<<*iter;
        }
    
        /*Remove_if + Erase Algorithm for one step removal*/
        v.erase( remove_if(v.begin(), v.end(), is_IndexEven), v.end() ); 
    
        /*Display result after elements removed*/
        cout<<"\nAfter\n";
        iter = v.begin();
        for(iter;iter!= v.end();++iter)
        {
           cout<<*iter;
        }
    
        return 0;
    }
    

    【讨论】:

    • 这就是我要找的。​​span>
    • +1。但是,remove_if 似乎根据元素的值删除了元素。它是否正确?如果我们想根据索引删除向量元素怎么办?
    • 正如 Benjamin Lindley 在an analogous answer to this similar question 上所做的那样,“这对remove_if 应用谓词的顺序做出了假设,标准文本并不保证这一点。”。
    【解决方案3】:

    为什么不使用remove_if?在函数内部使用静态变量来指示当前元素的索引。

    【讨论】:

    • 除了上面的答案之外,此链接中的示例代码正是您(OP)正在寻找的:cplusplus.com/reference/algorithm/remove_if
    • @yasouser,不,它没有,示例代码根据值是否偶数而不是它们的索引来删除项目。
    【解决方案4】:

    这里是如何使用擦除删除方法从向量中删除奇数。我不确定您是否可以根据索引删除元素,因为 remove_if() 将谓词应用于迭代器指向的值,而不是迭代器本身。

    请参阅以下内容: http://cplusplus.com/reference/algorithm/remove_if/

    #include <iostream>
    #include <algorithm>
    #include <vector>
    #include <iterator>
    using namespace std;
    
    int main()
    {
        vector<int> v;
        v.push_back(11);
        v.push_back(22);
        v.push_back(33);
        v.push_back(44);
        v.push_back(55);
        v.push_back(66);
        v.push_back(77);
        ostream_iterator<int> printit(cout, " ");
    
        cout << "Before removing odd numbers" << endl;
        copy(v.begin(), v.end(), printit);
    
    
        v.erase(remove_if(v.begin(), v.end(),
              [] (int e) { return e%2 == 1; }), v.end());
    
        cout << endl;
        cout << "After removing odd numbers" << endl;
        copy(v.begin(), v.end(), printit);
        cout << endl;
    }
    

    【讨论】:

    • “我不确定你是否可以根据索引删除元素......”这就是问题的重点。
    【解决方案5】:

    一个答案不仅概括了要处理的容器类型,而且概括了保存要删除的索引的容器类型,如下所示: Erasing elements in stl::vector by using indexes

    【讨论】:

      猜你喜欢
      • 2021-10-28
      • 1970-01-01
      • 2021-07-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-08
      • 2018-03-07
      相关资源
      最近更新 更多