欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

vector和map用erase删除元素

程序员文章站 2022-03-21 16:27:49
...

1、vector的删除

       vector的删除中,可以有erase和pop_back函数。erase可以删除指定元素或指定位置的元素,而pop_back只能去掉数组的最后一个元素。这里我们讨论erase函数的用法。

       假设有如下程序:

vector<int> vec;
vec.push_back(1);
vec.push_back(2);
vec.push_back(3);
vec.push_back(4);
vec.push_back(5);
for (vector<int>::iterator iter = vec.begin(); iter != vec.end(); iter++) {
	if (*iter == 3)
		vec.erase(iter);
}

       乍一看这段代码很正常,但这里面隐藏着一个很严重的错误:当vec.erase(iter)语句执行了之后,iter就变成了一个野指针,对一个野指针进行iter++操作是肯定会出错的。

       erase函数的返回值,是当前被删除元素的下一个元素的迭代器指针,于是改代码:

for (vector<int>::iterator iter = vec.begin(); iter != vec.end(); iter++) {
	if (*iter == 3)
		iter = vec.erase(iter);
}

       这段代码也是错误的:① 无法删除两个连续的3;② 当数字3位于vector最后位置的时候,也会出错(在vec.end()上执行++操作)。正确的代码应该如下所示:

#include <algorithm>
#include <vector>
#include <iostream>

using namespace std;

void PrintVec(int v) {
	cout << v << " ";
}

int main() {
	vector<int> vec;
	vec.push_back(1);
	vec.push_back(2);
	vec.push_back(3);
	vec.push_back(4);
	vec.push_back(1);
	vec.push_back(6);
	
	for_each(vec.begin(), vec.end(), PrintVec);
	cout << endl;
	
	cout << "----------" << endl;
	vector<int>::iterator iter;
	for (iter = vec.begin(); iter != vec.end(); ) {
		if (*iter == 1) {
			iter = vec.erase(iter);
			// vec.erase(iter++); //这种方式一样可以
		} else {
			++iter;
		}
	}
	
	for_each(vec.begin(), vec.end(), PrintVec);
	cout << endl;
	
	return 0;
}

程序的运行结果为:

1 2 3 4 1 6
----------
2 3 4 6

2、map的删除

       同理,map删除元素的方式是同样的,代码如下:

#include <map>
#include <string>
#include <iostream>

using namespace std;

int main() {
	map<int, string> map_student;
	
	map_student[1] = "student one";
	map_student[2] = "student two";
	map_student[3] = "student three";
	map_student[4] = "student four";
	map_student[5] = "student one";
	
	map<int, string>::iterator iter;
	for (iter = map_student.begin(); iter != map_student.end(); iter++) {
		cout << iter->first << " " << iter->second << endl;
	}
	
	cout << "---------------" << endl;
	
	iter = map_student.begin();
	for (; iter != map_student.end(); ) {
		if ((*iter).second == "student one") {
			map_student.erase(iter++);
			// iter = map_student.erase(iter); //用g++编译能通过但运行会出错,在vs上可以运行成功,why??
		} else {
			++iter;
		}
	}
	
	for (iter = map_student.begin(); iter != map_student.end(); iter++) {
		cout << iter->first << " " << iter->second << endl;
	}
	
	return 0;
} 

程序的运行结果是:

1 student one
2 student two
3 student three
4 student four
5 student one
---------------
2 student two
3 student three
4 student four

注意:map_student.erase(iter++); 中的iter++,不是erase(iter),然后iter++。因为iter指针被erase之后就失效了不能再++;也不是erase(++iter),这样就不是删除原来iter指向的元素了。至于为什么iter = map_student.erase(iter)用g++编译运行会失败,在vs上运行成功,暂时还不知道原因。

3、总结:

       在vector的erase删除中,用iter取得返回值或直接在erase函数中后++的方式都可以;而为了避免在编译环境下的区别,在map的erase删除中,最好使用erase中后++的方式删除元素。