刪除元素
刪除最後一個元素:
std::vector<int> v{ 1, 2, 3 };
v.pop_back(); // v becomes {1, 2}
刪除所有元素:
std::vector<int> v{ 1, 2, 3 };
v.clear(); // v becomes an empty vector
按索引刪除元素:
std::vector<int> v{ 1, 2, 3, 4, 5, 6 };
v.erase(v.begin() + 3); // v becomes {1, 2, 3, 5, 6}
注意: 對於 vector
刪除不是最後一個元素的元素,必須複製或移動刪除元素之外的所有元素以填補空白。
刪除範圍中的所有元素:
std::vector<int> v{ 1, 2, 3, 4, 5, 6 };
v.erase(v.begin() + 1, v.begin() + 5); // v becomes {1, 6}
注意: 上述方法不會改變向量的容量,只會改變大小。請參見向量大小和容量 。
刪除一系列元素的 erase
方法通常用作擦除 - 移除 習語的一部分。也就是說,首先 std::remove
將一些元素移動到向量的末尾,然後 erase
將它們關閉。對於小於向量的最後一個索引的任何索引,這是相對低效的操作,因為必須將擦除段之後的所有元素重新定位到新位置。對於需要有效刪除容器中任意元素的速度關鍵應用程式,請參閱 std::list 。
按值刪除元素:
std::vector<int> v{ 1, 1, 2, 2, 3, 3 };
int value_to_remove = 2;
v.erase(std::remove(v.begin(), v.end(), value_to_remove), v.end()); // v becomes {1, 1, 3, 3}
按條件刪除元素:
// std::remove_if needs a function, that takes a vector element as argument and returns true,
// if the element shall be removed
bool _predicate(const int& element) {
return (element > 3); // This will cause all elements to be deleted that are larger than 3
}
...
std::vector<int> v{ 1, 2, 3, 4, 5, 6 };
v.erase(std::remove_if(v.begin(), v.end(), _predicate), v.end()); // v becomes {1, 2, 3}
通過 lambda 刪除元素,而不建立其他謂詞函式
Version => C++ 11
std::vector<int> v{ 1, 2, 3, 4, 5, 6 };
v.erase(std::remove_if(v.begin(), v.end(),
[](auto& element){return element > 3;} ), v.end()
);
從迴圈中按條件刪除元素:
std::vector<int> v{ 1, 2, 3, 4, 5, 6 };
std::vector<int>::iterator it = v.begin();
while (it != v.end()) {
if (condition)
it = v.erase(it); // after erasing, 'it' will be set to the next element in v
else
++it; // manually set 'it' to the next element in v
}
雖然重要的是不要在刪除時增加 it
,但是在迴圈中重複擦除時應考慮使用不同的方法。考慮 remove_if
以獲得更有效的方式。
從反向迴圈中按條件刪除元素:
std::vector<int> v{ -1, 0, 1, 2, 3, 4, 5, 6 };
typedef std::vector<int>::reverse_iterator rev_itr;
rev_itr it = v.rbegin();
while (it != v.rend()) { // after the loop only '0' will be in v
int value = *it;
if (value) {
++it;
// See explanation below for the following line.
it = rev_itr(v.erase(it.base()));
} else
++it;
}
請注意前一個迴圈的一些要點:
-
給定一個指向某個元素的反向迭代器
it
,方法base
給出了指向同一元素的常規(非反向)迭代器。 -
vector::erase(iterator)
擦除迭代器指向的元素,並將迭代器返回給定元素後面的元素。 -
reverse_iterator::reverse_iterator(iterator)
從迭代器構造一個反向迭代器。
總而言之,線 it = rev_itr(v.erase(
it.base()))
說:取反向迭代器 it
,讓 v
擦除其常規迭代器指向的元素; 獲取生成的迭代器,從中構造一個反向迭代器,並將其分配給反向迭代器 it
。
使用 v.clear()
刪除所有元素不會釋放記憶體( 向量的 capacity()
保持不變)。要回收空間,請使用:
std::vector<int>().swap(v);
Version => C++ 11
shrink_to_fit()
釋放未使用的向量容量:
v.shrink_to_fit();
shrink_to_fit
並不能保證真正回收空間,但大多數現有的實施都可以。