日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

一起來學習C++中remove與erase的理解_C 語言

作者:Giant?NG ? 更新時間: 2022-05-10 編程語言

erase 簡介

vector?中?erase?函數原型如下:

iterator erase(
    const_iterator position);
iterator erase(
    const_iterator first,
    const_iterator last);

用于刪除 vector 容器中的一個或者一段元素

在刪除一個元素的時候,其參數為指向相應元素的迭代器;而在刪除一段元素的時候,參數為指向一段元素的開頭的迭代器以及指向結尾元素的下一個元素的迭代器

調用?erase?后,vector?元素會向前移,因此需要格外注意這個特征,避免越界訪問以及漏處理。

示例代碼:

int main(int argc, char *argv[])
{
	vector myVector;
	myVector.push_back(1);
	myVector.push_back(2);
	myVector.push_back(3);
	myVector.push_back(3);
	myVector.push_back(3);
	myVector.push_back(4);
	myVector.push_back(3);
	myVector.push_back(3);
	myVector.push_back(3);
	for (vector::iterator itr = myVector.begin(); itr != myVector.end(); itr++) {
		if (*itr == 3) {
			//此時itr已經指向了新的下一個元素;如果不執行itr--與itr++做抵消,則會超出end導致崩潰。
			itr = myVector.erase(itr);
			itr--;
		}
	}
	cout << "[After erase] myVector: ";
	for (int temp : myVector)
		cout << temp << " ";
	cout << endl;
	return 0;
}

remove 簡介

algorithm?中?remove?原型如下:

template
ForwardIterator remove(
    ForwardIterator first,
    ForwardIterator last,
    const Type& value);
template
ForwardIterator remove(
    ExecutionPolicy&& exec,
    ForwardIterator first,
    ForwardIterator last,
    const Type& value);

remove?函數是由?STL?庫中?algorithm?提供的一個函數,這里的?remove?字面意思很容易引起初學者誤解。因為調用以后并非真實的?remove

代碼示例

#include 
#include 
#include 
using namespace std;
int main(int argc, char *argv[])
{
	vector array;
	array.push_back(1);
	array.push_back(2);
	array.push_back(3);
	array.push_back(3);
	array.push_back(4);
	array.push_back(5);
	cout << "init : ";
	print(array);
	array.erase(array.begin());
	cout << "erase array.begin() :";
	print(array);
	vector::iterator remove2It = remove(array.begin(), array.end(), 2);
	cout << "remove 2 : ";
	print(array);
	cout << "remove2It traverse : ";
	for (; remove2It != array.end(); remove2It++)
		cout << *remove2It << " ";
	cout << endl;
	vector::iterator remove3It = remove(array.begin(), array.end(), 3);
	cout << "remove 3 : ";
	print(array);
	cout << "remove3It traverse : ";
	for (; remove3It != array.end(); remove3It++)
		cout << *remove3It << " ";
	cout << endl;
	return 0;
}

運行后打印如下:

init : 1 2 3 3 4 5
erase array.begin() :2 3 3 4 5
remove 2 : 3 3 4 5 5
remove2It traverse : 5
remove 3 : 4 5 5 5 5
remove3It traverse : 5 5

代碼分析

如上所示,執行?array.erase(array.begin());?后,符合預期地將第一個元素刪除了,打印結果為:erase array.begin() : 2 3 3 4 5

在此基礎(2 3 3 4 5)上執行?remove(array.begin(), array.end(), 2);,可能慣性思維會覺得得到的結果(這個是錯誤的結果,效果就像調用了 erase 一樣)應該是?3 3 4 5,4 個元素。而實際打印結果為:3 3 4 5 5,5 個元素。這里完全“顛覆”了對 remove 這一字義的認識。

remove 是如何工作的?

查找資料后發現,remove?和?erase?存在很大的區別。

remove?是?algorithm?的模板函數,它接收的都是迭代器參數,并不接收某個容器。remove?并不知道它作用于哪個容器,也不可能發現容器,因為沒有辦法從一個迭代器獲得對應于它的容器。

想要從容器中刪除一個元素,唯一的方法就是調用容器的一個成員函數,比如?erase?函數。而?remove?無法知曉,故不可能根據一個傳進來的迭代器進而在該容器中除去元素。因此,調用?remove?后并不會改變該容器的元素個數

得出的結論是:remove?并不是真的在刪除元素,因為它根本做不到

remove 的工作流程

在這里插入圖片描述

(注意:begin?與?end?是左閉右開區間,即?end?是?vector?之外了,即?vector?最后一個元素的下一個。)

這里需要明確一點是,remove()?的返回值是一個?iterator

再來看 remove(3) 的過程:

在這里插入圖片描述

至此,大概可以弄清楚?remove?這個函數對一個?vector?做了哪些操作,改變了哪些元素的順序,以及返回值是指向何處

總結

原文鏈接:https://blog.csdn.net/ZefinNg/article/details/123341995

欄目分類
最近更新