如何通过索引擦除std :: vector <>中的元素?

我有一个std :: vector <int>,我想删除第n个元素。 我怎么做?

std::vector<int> vec; vec.push_back(6); vec.push_back(-17); vec.push_back(12); vec.erase(???); 

要删除一个元素,你可以这样做:

 std::vector<int> vec; vec.push_back(6); vec.push_back(-17); vec.push_back(12); // Deletes the second element (vec[1]) vec.erase(vec.begin() + 1); 

或者,一次删除多个元素:

 // Deletes the second through third elements (vec[1], vec[2]) vec.erase(vec.begin() + 1, vec.begin() + 3); 

std :: vector上的擦除方法被重载了,所以调用的时候可能会更清楚

 vec.erase(vec.begin() + index); 

当你只想擦除一个单一的元素。

 template <typename T> void remove(std::vector<T>& vec, size_t pos) { std::vector<T>::iterator it = vec.begin(); std::advance(it, pos); vec.erase(it); } 

erase方法将以两种方式使用:

  1. 擦除单个元素:

     vector.erase( vector.begin() + 3 ); // Deleting the third element 
  2. 擦除元素的范围:

     vector.erase( vector.begin() + 3, vector.begin() + 5 ); // Deleting from third element to fifth element 

要使用以下方法删除元素:

  1 // declaring and assigning array1 2 std:vector<int> array1 {0,2,3,4}; 3 4 // erasing the value in the array 5 array1.erase(array1.begin()+n); 

更广泛的概述,您可以访问: – http://www.cplusplus.com/reference/vector/vector/erase/

实际上, erasefunction适用于两个configuration文件:

  • 删除单个元素

     iterator erase (iterator position); 
  • 删除一系列元素

     iterator erase (iterator first, iterator last); 

由于std :: vec.begin()标记容器的开始,如果我们想要删除vector中的第i个元素,我们可以使用:

 vec.erase(vec.begin() + index); 

如果仔细观察,vec.begin()只是一个指向我们的向量的起始位置的指针,并且将它的值加到它将指针递增到i位置,所以我们可以通过以下方式访问指向第i个元素的指针:

 &vec[i] 

所以我们可以写:

 vec.erase(&vec[i]); // To delete the ith element 

以前的答案假定你总是有一个签名索引。 可悲的是, std::vector使用size_type作为索引,而difference_type用于迭代器算术,所以如果你有“-Wconversion”和朋友启用,它们不能一起工作。 这是解决问题的另一种方式,同时能够处理签名和未签名:

去除:

 template<class T, class I, class = typename std::enable_if<std::is_integral<I>::value>::type> void remove(std::vector<T> &v, I index) { const auto &iter = v.cbegin() + gsl::narrow_cast<typename std::vector<T>::difference_type>(index); v.erase(iter); } 

采取:

 template<class T, class I, class = typename std::enable_if<std::is_integral<I>::value>::type> T take(std::vector<T> &v, I index) { const auto &iter = v.cbegin() + gsl::narrow_cast<typename std::vector<T>::difference_type>(index); auto val = *iter; v.erase(iter); return val; } 

如果你有一个无序的向量,你可以利用它无序的事实,并使用我在CPPCON的Dan Higgins看到的东西

 template< typename TContainer > static bool EraseFromUnorderedByIndex( TContainer& inContainer, size_t inIndex ) { if ( inIndex < inContainer.size() ) { if ( inIndex != inContainer.size() - 1 ) inContainer[inIndex] = inContainer.back(); inContainer.pop_back(); return true; } return false; } 

由于列表顺序无关紧要,只需将列表中的最后一个元素复制到要删除的项目的顶部,然后popup并删除最后一个项目。

如果你使用大的向量(大小> 100,000),并想删除大量的元素,我会build议做这样的事情:

 int main(int argc, char** argv) { vector <int> vec; vector <int> vec2; for (int i = 0; i < 20000000; i++){ vec.push_back(i);} for (int i = 0; i < vec.size(); i++) { if(vec.at(i) %3 != 0) vec2.push_back(i); } vec = vec2; cout << vec.size() << endl; } 

该代码将vec中的每个数字都不能被3除,并将其复制到vec2。 之后它在vec中复制vec2。 这是非常快的。 要处理20,000,000个元素,这个algorithm只需要0.8秒!

我用擦除方法做了同样的事情,而且花费了很多时间:

 Erase-Version (10k elements) : 0.04 sec Erase-Version (100k elements) : 0.6 sec Erase-Version (1000k elements): 56 sec Erase-Version (10000k elements): ...still calculating (>30 min)