如何通过值从向量中删除元素,但只删除该值的单个实例?

时间:2014-07-27 07:17:13

标签: c++ vector

这是问题,

我有一个向量,我需要一个接一个地从向量中删除2个元素。我知道这两个元素的价值和这些元素的索引。

首先,我尝试使用索引删除这两个元素,即

v.erase(v.begin()+index1);
v.erase(v.begin()+index2);

但问题是在擦除数组中第二个元素的第一个元素索引后发生了变化。

所以,我试图按价值删除它们,即

v.erase(remove(v.begin(),v.end(),value),v.end());

但是这会移除该值的所有实例(例如,如果有2" 1"它将删除它们两者),而我只想删除一个元素。

如何解决?

2 个答案:

答案 0 :(得分:0)

您可以使用:

v.erase(v.begin() + std::max(index1, index2));
v.erase(v.begin() + std::min(index1, index2));

甚至

auto indexes = std::minmax(index1, index2);
v.erase(v.begin() + indexes.second);
v.erase(v.begin() + indexes.first);

答案 1 :(得分:0)

std::vector<>中删除元素时,擦除点处或之后的任何迭代器都将失效。

这就是为什么必须首先删除位于索引较大位置的元素。

示例:

using namespace std;

int main() 
{
  vector<int> v { 1, 2, 3, 4, 5, 6, 7};

  size_t index1 = 3; // We want to remove 4
  size_t index2 = 5; // We want to remove 6

  v.erase(begin(v) + index2); // We remove the element with the greater index first
  v.erase(begin(v) + index1); // fine, v.begin() + index1 is BEFORE the previous point of erasure

  for(auto val : v)
    cout << val << " ";

  return 0;
}

修改:

  • 这是一个通用算法remove_at_indexes,用于通过指定范围(std::size_t
  • 形式的索引从容器中删除元素
  • 它适用于任何符合STL标准的容器(vectorstringdeque ...)

<强>代码:

template<class Iterator, class IteratorId>
Iterator remove_at_indexes(Iterator first, Iterator last, IteratorId indexes_begin, IteratorId indexes_end)
{
    std::sort(indexes_begin, indexes_end, std::less<size_t>());

    std::size_t count { 0 };

    if (first != last)
        for(auto i = first; i != last; i++)
            if(indexes_begin == indexes_end)
               first++;
            else
            {
                if (count != *indexes_begin)
                    *first++ = std::move(*i);
                else
                    indexes_begin++;
                count++;
            }

    return first;
}

用法示例:

  vector<int> v { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
  vector<size_t> indexes { 4, 1, 9 };

  v.erase(remove_at_indexes(v.begin(), v.end(), indexes.begin(), indexes.end()), v.end());

输出

  

1 3 4 6 7 8 9

Demo here