顺序容器:删除元素的操作

一、pop_front与pop_back:

/*
c.pop_back()
	删除容器 c 的最后一个元素。返回 void。如果 c 为空容器,则该函数未定义
c.pop_front()
	删除容器 c 的第一个元素。返回 void。如果 c 为空容器,则该函数未定义只适用于 list 或 deque 容器
*/
void test_pop()
{
	std::deque<int> de;
	for( int i = 0; i != 5; ++i )
	{
		de.push_back(i);
	}

	if( !de.empty() ) // 一定要保证de不为空
	{
		//de.pop_front();
		de.pop_back();
	}
	for( unsigned int i = 0; i != de.size(); ++i )
	{
		std::cout << de.at(i) << "_";
	}
	std::cout << std::endl;

	while( !de.empty() )
	{
		de.pop_front();
	}
}

二、测试erase与clear函数:

// 如果容器为空,则begin和end相等,不执行循环体
void print_deque( std::deque<int>::const_iterator begin, std::deque<int>::const_iterator end )
{
	while( begin != end )
	{
		std::cout << *begin << "_";
		++begin;
	}
	std::cout << std::endl;
}

void test_erase_clear()
{
	std::deque<int> de;
	for( int i = 0; i != 10; ++i )
	{
		de.push_back(i);
	}
	print_deque(de.begin(), de.end());	// 0_1_2_3_4_5_6_7_8_9_

	// erase:
	// 删除迭代器 p 所指向的元素,返回一个迭代器,它指向被删除元素后面的元素 如果 p 指向容器内的
	// 最后一个元素,则返回的迭代器指向容器的超出末端的下一位置。如果 p 本身就是指向超出末端的
	// 下一位置的迭代器,则该函数未定义
	std::deque<int>::iterator r1 = de.erase(de.begin()+1);
	std::cout << *r1 << std::endl;

	print_deque(de.begin(), de.end());	// 0_2_3_4_5_6_7_8_9_

	//左开右闭[0,3),即删除两个迭代器之间的元素,包括第一个但不包括第二个
	std::deque<int>::iterator r2 = de.erase(de.begin(), de.begin()+2);
	std::cout << *r2 << std::endl;	// 3

	print_deque(de.begin(), de.end());	// 3_4_5_6_7_8_9_

	// 删除容器 c 内的所有元素,返回 void
	//de.clear();

	// 或者采用erase操作删除所有元素,返回容器最后一个元素的下一位
	de.erase(de.begin(), de.end());

}

三、测试标准库头文件algorithm中的find函数:

// 测试:在vector<int>查找某个元素,如果有返回这个元素的迭代器
std::vector<int>::iterator find_1( std::vector<int>::iterator first, std::vector<int>::iterator last, int &value )
{
	while( first != last )
	{
		if( value == *first )
		{
			return first;
		}
		++first;
	}
	return last;
}

void test_find_1()
{
	std::vector<int> vec;
	for( int i = 0; i != 100; ++i )
	{
		vec.push_back(i);
	}
	int value = 1322;
	//int value = 55;
	std::vector<int>::iterator it = find_1(vec.begin(), vec.end(), value);
	if( it != vec.end() )
	{
		std::cout << "OK:" << *it << std::endl;		// OK:55
	}
	else
	{
		std::cout << "NOT FIND:" << value << ", End is : " << *it << std::endl;	// NOT FIND:1322, End is : 0
	}
}

// 利用标准库实现的find函数,但要包括头文件:algorithm:#include <algorithm>
void test_find_2()
{
	std::vector<int> vec;
	for( int i = 0; i != 100; ++i )
	{
		vec.push_back(i);
	}
	//int value = 1322;
	int value = 55;

	std::vector<int>::iterator it = std::find(vec.begin(), vec.end(), value);
	if( it != vec.end() )
	{
		std::cout << "OK:" << *it << std::endl;		// OK:55
	}
	else
	{
		std::cout << "NOT FIND:" << value << ", End is : " << *it << std::endl;	// NOT FIND:1322, End is : 0
	}
}

四、两个习题:

1、需要删除一段元素时,如果 val1 与 val2 相等,那么程序会发生什么事情?如果 val1 和 val2 中的一个不存在,或两个都不存在,程序又会怎么样?

如果ival1与ival2相等,则不会删除任何元素;

如果ival1与ival2中的任何一个不存在,或两个都不存在,则会发生运行时错误。


2、假设有如下 ia 的定义,将 ia 复制到一个 vector 容器和一个 list 容器中。使用单个迭代器参数版本的 erase函数将 list 容器中的奇数值元素删除掉,

然后将vector 容器中的偶数值元素删除掉:int ia[] = { 0, 1, 1, 2, 3, 5, 8, 13, 21, 55,89 };

void print_list( std::list<int> &lst )
{
	std::list<int>::iterator it = lst.begin();
	while( it != lst.end() )
	{
		std::cout << *it << "_";
		++it;
	}
	std::cout << std::endl;
}
void print_vector( std::vector<int> &vec )
{
	std::vector<int>::iterator it = vec.begin();
	while( it != vec.end() )
	{
		std::cout << *it << "_";
		++it;
	}
	std::cout << std::endl;
}

// 在删除元素后迭代器会失效,因此一定要对迭代器重新赋值,另外,erase函数返回一个迭代器,指向被删除元素的下一位元
// 素,因为在for语句中要对迭代器加1,所以在if语句中将迭代器减1,以免遗漏需处理的元素
void test_9_25()
{
	int ia[] = { 0, 1, 1, 2, 3, 5, 8, 13, 21, 55, 89 };
	std::list<int> 		lst(ia, ia+11);
	std::vector<int> 	vec(ia, ia+11);

	// 删除奇数值:list
	for( std::list<int>::iterator it = lst.begin(); it != lst.end(); ++it )
	{
		if( (*it) % 2 == 1 )
		{
			it = lst.erase(it);
			--it;		// 迭代器回退
		}
	}
	print_list(lst);	// 0_2_8_

	// 删除偶数值:vector
	for( std::vector<int>::iterator it = vec.begin(); it != vec.end(); ++it )
	{
		if( (*it) % 2 == 0 )
		{
			it = vec.erase(it);
			--it;		// 迭代器回退
		}
	}
	print_vector(vec);	// 1_1_3_5_13_21_55_89_
}






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值