c++ primer(第五版)笔记 第九章 顺序容器(2)

31 篇文章 0 订阅
// 顺序容器
// 添加元素(array 除外)
	// 在尾部创建一个值为 t 或由 args 创建的元素,返回 void,不支持 forward_list 
	// c.push_back(t)
	// c.emplace_back(args)
	
	// 在头部创建一个值为 t 或由 args 创建的元素,返回 void,不支持 vector 和 string 
	// c.push_front(t)
	// c.emplace_front(args)
	
	// 在迭代器 p 指向的元素之前创建一个值为 t 或由 args 创建的元素,返回新添加的元素迭代器
	// forward_list有自身独有的 insert 和 emplace
	// c.insert(p,t)
	// c.emplace(p,args)
	
	// 在迭代器 p 指向的元素之前插入 n 个值为 t 的元素,返回指向新添加的第一个元素的迭代器,若 n 为 0,返回 p
	// c.insert(p,n,t)
	
	// 在迭代器 p 指向的元素之前插入迭代器 b,e 指定范围内的元素,返回指向新添加的第一个元素的迭代器,若 n 为 0,返回 p,b,e 不能指向 c 中的元素
	// c.insert(p,b,e)
	
	// 在迭代器 p 指向的元素之前插入元素值列表 {li},返回指向新添加的第一个元素的迭代器,若 n 为 0,返回 p
	// c.insert(p,li)
	
	// 向 vector deque string 插入一个元素,会使指向该容器的迭代器,指针,引用失效
	// 向 vector string 尾部之外的位置,deque 头尾之外的位置插入元素,都需要移动元素
	// 而且向 vector string 添加元素还可能引起对整个对象存储空间的重新分配

//容器访问
	//所有容器,包括 array 都有一个 front 成员函数,返回首元素的引用
	//除 forward_list 外,所有容器都一个 back 成员函数,返回尾元素的引用
	//如果为空,函数行为是未定义的
	// string vector deque array 提供下标运算,下标是无符号整数,如果大于等于容器大小,是未定义行为
	//at 成员函数类型下标运算,但如果下标越界,会抛出 out_of_range 的异常	

// 删除元素(array 除外)
	// 删除尾元素,若 c 为空,行为未定义,返回 void,不支持 forward_list 
	// c.pop_back()
	
	// 删除首元素,若 c 为空,行为未定义,返回 void,不支持 vector 和 string 
	// c.pop_front()	
	
	// forward_list 有自己版本的 erase
	// 删除迭代器 p 指向的元素,返回一个指向被删除元素之后的元素的迭代器,若 p 指向尾元素,返回尾后迭代器,若 p 是尾后迭代器,行为未定义
	// c.erase(p);
	
	// 删除 b,e 迭代器范围内的元素,返回一个指向最后一个被删除元素之后的元素的迭代器,若 e 是尾后迭代器,则返回尾后迭代器
	// c.earse(b,e);
	
	// 删除所有元素,返回 void
	// c.clear();
	
	// 删除 deque 首尾位置之外的元素,会使所有迭代器,指针,引用失效
	// 删除 vector string 中的元素,指向删除点之后位置的迭代器,指针,引用失效
	
// forward_list 操作
	// 返回指向首元素之前不存在的元素的迭代器,不可以解引用
	// c.before_begin()
	
	// 返回指向首元素之前不存在的元素的 const 迭代器,不可以解引用
	// c.cbefore_begin()
	
	// 在迭代器 p 之后的位置插入,若 p 是 off of end 迭代器,行为未定义
	// c.insert_after(p,t)
	// c.insert_after(p,n,t)
	// c.insert_after(p,b,e)
	// c.insert_after(p,li)

	// 在 p 后插入一个用 args 构建的元素,返回这个新元素的迭代器,若 p 是 off of end 迭代器,行为未定义
	// c.emplace_after(p,args)
	
	// 删除 p 位置之后的元素或者从 b 之后到(不包括)e之间的元素,返回删除元素之后元素的迭代器,若 p 是尾元素迭代器或 off of end 迭代器,行为未定义
	// c.erase(p)
	// c.erase(b,e)

// 改变容器大小,会导致迭代器失效
	// 调整 c 的大小为 n 个元素,若 n < c.size(),多出的元素被丢弃,若需要添加新元素,对新元素执行值初始化
	// c.resize(n)
	
	// 调整 c 的大小为 n 个元素,所有新加元素初始化为 t
	// c.resize(n,t)
	
// 容器操作对迭代器的影响
	// 添加元素
		// 1>如果是 vector string,且存储空间被重新分配,则指向容器的所有迭代器,指针,引用都会失效
			// 如果未重新分配空间,则指向插入位置前的元素迭代器,指针,引用仍有效,之后的均失效
			
		// 2>如果是 deque,在首尾之外位置插入元素,会导致指向容器的所有迭代器,指针,引用失效
			// 如果在首尾插入元素,迭代器会失效,指针,引用仍然有效
		
		// 3>如果是 list  forward_list ,无影响,均有效
		
	// 删除元素,被删除的元素的迭代器,指针,引用失效
		// 1>对于 list  forward_list 其他位置的元素,无影响,均有效
		// 2>对于 vector string,指向被删元素之前的迭代器,指针,引用仍有效,但尾后迭代器总是失效
		// 3>对于 deque,如果在首尾之外的位置删除元素,那么其他位置的迭代器,指针,引用都会失效
			// 如果是删除尾元素,则尾后迭代器失效,其他无影响,如果是首元素,也无影响
		
#include<stdexcept>
#include<string>
#include<iostream>
#include<deque>
#include<list>
#include<vector>
#include<forward_list>

using std::out_of_range;
using std::string;
using std::list;
using std::vector;
using std::forward_list;
using std::deque;
using std::cout;
using std::cin;
using std::endl;

void practice_918();
void practice_919();
void practice_924();
void practice_925();
void practice_926();
void practice_927();	
void practice_928(forward_list<string> &fi, string &sa, string &sb);

int main()
{
	// practice_918();
	// practice_919();
	// practice_924();
	// practice_925();
	// practice_926();
	// practice_927();
	
	forward_list<string> fs{"hello", "world", "mamamia", "bye"};
	string sa{"wold"};
	string sb{"i'm coming"};
	practice_928(fs, sa, sb);
	return 1;
}
//从流中读入string, 压入 deque 或 list
void practice_918()
{
	//写入
	string stmp;
	deque<string> ds;
	list<string> ls;
	while(cin >> stmp)
	{
		// ds.push_back(stmp);
		ls.push_back(stmp);
	}
	//输出
	// auto di = ds.cbegin();
	auto di = ls.cbegin();
	// while(di != ds.cend())
	while(di != ls.cend())
	{
		cout << *di << endl;
		++di;
	}
}
// 将 list<int> 中元素,按奇偶压入 2个deque
void practice_919()
{
	list<int> li{234,1327,8254,9123,823,753,18,37,74,398,1};
	deque<int> di_even, di_odd;
	auto lii = li.cbegin();
	while(lii != li.cend())
	{
		if(!(*lii % 2 ))
			di_even.push_front(*lii);
		else
			di_odd.push_front(*lii);
		++lii;
	}
	for(auto i : di_even)
		cout << "di_even:" << i << endl;
	for(auto i : di_odd)
		cout << "di_odd:" << i << endl;
}
//顺序容器的访问
void practice_924()
{
	deque<int> vi{234,1327,8254,9123,823,753,18,37,74,398,1};
	cout << "vi.first = " << vi.front() << endl;
	cout << "vi.first = " << *(vi.begin()) << endl;
	cout << "vi.first = " << vi[0] << endl;
	cout << "vi.first = " << vi.at(0) << endl;
	vi.clear();	//清空
	try
	{
		cout << "vi.first = " << vi.at(0) << endl;
	}
	catch(out_of_range err)	//捕捉 out_of_range 异常
	{
		cout << "vi is empty" << endl;
	}
	cout << "vi.first = " << vi[0] << endl;	//未定义行为
}
//删除容器元素
void practice_925()
{
	deque<int> vi{234,1327,8254,9123,823,753,18,37,74,398,1};
	
	deque<int>::iterator fi = vi.begin() + 3;
	deque<int>::iterator ei = vi.begin() + 5;
	auto res = vi.erase(fi,ei);
	cout << "result of erase = " << *res << endl;
	for(auto i : vi)
		cout << "i : vi = " << i << endl;
		
	cout << "******************" << endl;
	// 如果 erase 传入2个相等的迭代器,不会删除元素,该迭代器
	fi = vi.begin() + 3;
	ei = vi.begin() + 3;
	res = vi.erase(fi,ei);
	cout << "result of erase = " << *res << endl;
	for(auto i : vi)
		cout << "i : vi = " << i << endl;
		
	cout << "******************" << endl;
	// 如果 erase 传入2个尾后的迭代器,不会删除元素,该尾后迭代器
	fi = vi.end();
	ei = vi.end();
	res = vi.erase(fi,ei);
	if(res == vi.end())
		cout << "result of erase is off of end! " << endl;
	for(auto i : vi)
		cout << "i : vi = " << i << endl;
}

//删除容器元素
void practice_926()
{
	int ai[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
	list<int> li(ai, ai + sizeof(ai) / sizeof(int));
	vector<int> vi(ai, ai + sizeof(ai) / sizeof(int));
	
	for(auto i : li)
		cout << i << "  -  ";
	cout << endl;
	for(auto i : vi)
		cout << i << "  -  ";
	cout << endl;
	cout << "******************" << endl;
	//按奇偶删除元素
	for(auto ii = li.begin(); ii != li.end();)
	{
		if(*ii % 2)
			++ii;
		else
			ii = li.erase(ii);
	}
	for(auto ii = vi.begin(); ii != vi.end();)
	{
		if(*ii % 2)
			ii = vi.erase(ii);
		else
			++ii;
	}
	cout << "******************" << endl;
	for(auto i : li)
		cout << i << "  -  ";
	cout << endl;
	for(auto i : vi)
		cout << i << "  -  ";
	cout << endl;
}

//从 forward_list 中删除元素
void practice_927()
{
	int ai[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
	forward_list<int> fi(ai, ai + sizeof(ai) / sizeof(int));
	
	auto fii = fi.begin();
	auto bfii = fi.before_begin();
	while(fii != fi.end())
	{
		if(*fii % 2)
		{
			fii = fi.erase_after(bfii);
		}
		else
		{
			bfii = fii;
			++fii;
		}
	}
	cout << "******************" << endl;
	for(auto i : fi)
		cout << i << "  -  ";
	cout << endl;
}

//在 forward_list 中查找 sa,将sb 插入其后,若找不到 sa,将sb 插到末尾
void practice_928(forward_list<string> &fi, string &sa, string &sb)
{
	auto fii = fi.begin();
	auto bfii = fi.before_begin();
	while(fii != fi.end())
	{
		if(*fii == sa)
		{
			fii = fi.insert_after(fii,sb);
			break;
		}
		else
		{
			bfii = fii;
			++fii;
		}
	}
	if(fii == fi.end())
		fi.insert_after(bfii, sb);
	
	cout << "******************" << endl;
	for(auto i : fi)
		cout << i << "  -  ";
	cout << endl;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值