How do I erase an element from std::vector<> by index?
我有一个std::vector
1 2 3 4 5 6 7 | std::vector<int> vec; vec.push_back(6); vec.push_back(-17); vec.push_back(12); vec.erase(???); |
要删除单个元素,可以执行以下操作:
1 2 3 4 5 6 7 8 | 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); |
或者,一次删除多个元素:
1 2 | // Deletes the second through third elements (vec[1], vec[2]) vec.erase(vec.begin() + 1, vec.begin() + 3); |
std::vector上的erase方法被重载,因此调用
1 | vec.erase(vec.begin() + index); |
当您只想删除一个元素时。
1 2 3 4 5 6 7 | 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); } |
删除单个元素:
1 | vector.erase( vector.begin() + 3 ); // Deleting the fourth element |
删除元素范围:
1 | vector.erase( vector.begin() + 3, vector.begin() + 5 ); // Deleting from fourth element to sixth element |
如果你有一个无序向量,你可以利用它无序的事实,使用我在CPPCON从丹·希金斯那里看到的东西。
1 2 3 4 5 6 7 8 9 10 11 12 | 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; } |
由于列表顺序无关紧要,只需将列表中的最后一个元素复制到要删除的项的顶部,然后弹出并删除最后一个项。
实际上,
移除单个元素
1iterator erase (iterator position);删除一系列元素
1iterator erase (iterator first, iterator last);
因为std::vec.begin()标记容器的开始,如果我们想删除向量中的ith元素,可以使用:
1 | vec.erase(vec.begin() + index); |
如果仔细观察,vec.begin()只是一个指向向量起始位置的指针,向其添加i值会使指向i位置的指针递增,因此我们可以通过以下方式访问指向ith元素的指针:
1 | &vec[i] |
所以我们可以写:
1 | vec.erase(&vec[i]); // To delete the ith element |
如果您使用大向量(大小大于100000)并希望删除大量元素,我建议您执行以下操作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 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。速度相当快。要处理20000000个元素,此算法只需0.8秒!
我用擦除方法做了同样的事情,它需要很多时间:
1 2 3 4 | 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) |
要删除元素,请使用以下方法:
1 2 3 4 5 | // declaring and assigning array1 std:vector<int> array1 {0,2,3,4}; // erasing the value in the array array1.erase(array1.begin()+n); |
有关更广泛的概述,请访问:http://www.cplusplus.com/reference/vector/vector/erase/
这里还有一种方法可以做到这一点,如果你想删除一个元素,通过找到它在向量中的值,你只需要在向量上做这个。
1 2 | vector<int> ar(n); ar.erase(remove(ar.begin(), ar.end()), (place your value here from vector array)); |
它将从这里移除您的值。谢谢
前面的答案假设您总是有一个有符号的索引。遗憾的是,
移除:
1 2 3 4 5 6 | template<class T, class I, class = typename std::enable_if<std::is_integral::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); } |
采取:
1 2 3 4 5 6 7 8 9 10 | template<class T, class I, class = typename std::enable_if<std::is_integral::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; } |