Day 18 C++提高 之 STL常用容器(string、vector、deque)

Day 18 C++提高 之 STL常用容器

一、string 容器
1.string 基本概念

本质:string 是 C++ 风格的字符串,而 string 本质上是一个类

string 和 char * 的区别:

  • char * 是一个指针;
  • string 是一个类,类内部封装了 char * ,管理这个字符串,是一个 char * 型的容器,(即字符数组,数组内每个元素都是一个字符,多个字符链接在一起就是字符串;char* 是一个指针,指向这个字符数组)

特点:

  • string 类内部封装了很多成员方法;例如:查找 find、拷贝 copy、删除 delete、替换 replace、插入 insert;
  • string 管理 char * 所分配的内存,(别人已经完全写好了)不用担心赋值越界和取值越界等,由类内部进行负责
2.string构造函数

构造函数原型:

c++ 复制代码
string();                  //无参,默认构造创建一个空的字符串,例如 string str;
string(const char* s);     //使用字符串s初始化,传一个c的字符串
string(const string& str); //使用一个已知的string对象初始化另一个string对象
string(int n,char c);      //使用n个字符c初始化字符串


void test01()
{
	string s1;         //默认构造,创建一个字符串s1

	const char * str= "hello world!";//使用字符串str初始化一个字符串
	string s2(str);
	cout << "s2 =" << s2 << endl;

	const string& str1 = "懒羊羊";//拷贝构造,使用一个string对象初始化另一个对象
	string s3(str1);//string s3(s2)
	cout << s3 << endl;

	string s4(8, 'a');//使用n个字符c初始化字符串
	cout << s4 << endl;
}

string 的有多种构造方式,可以灵活使用

3.string 赋值操作

给string字符串进行赋值。两种方式( = 与 assign )赋值的函数原型:

c++ 复制代码
//等号
string& operator=(const char *s);        //char* 类型字符串,赋值给当前的字符串
string& operator=(const string &s);      //把字符串s赋值给当前的字符串
string& operator=(char c);               //字符赋值给当前的字符串

//assign
string& assign=(const char *s);          //把字符传s赋值给当前的字符串
string& assign=(const char *s,int n);    //把字符串s的前n个字符赋值给当前的字符串
string& assign=(const string &s);        //把字符串s赋值给当前字符串
string& assign=(int n,char c);           //用n个字符c赋值给当前的字符串

操作示例:

c++ 复制代码
void test01()
{
	//1.等号方法
	string str1;//相当于等号赋值,直接等
	str1 = "hello world!";//利用等号的方法直接就是const char*方式进行赋值
	cout << str1 << endl;

	string str2;
	str2 = str1;//直接把一个字符串赋值给另一个字符串,类似于拷贝构造,相当于等号赋值
	cout << str2 << endl;

	string str3;
	str3 = 'a';//单个字符给字符串赋值
	cout << str3 << endl;


	//2.assign赋值(成员函数赋值)
	string str4;
	str4.assign("欢迎来到青青草原!");//把c语言字符串直接往里面传
	cout << str4 << endl;

	string str5;
	str5.assign("I am lyy,我是懒羊羊!也是懒大厨!美食评鉴师!", 5);//有一个参数5,就是将字符串前5个字符赋值给字符串
	cout << str5 << endl;

	string str6;
	str6.assign(str5);
	cout << str6 << endl;

	string str7;
	str7.assign(6, 'a');
	cout << str7 << endl;
}
4.string 字符串拼接

实现在字符串末尾拼接字符串(+=操作符重载,append函数);函数原型:

c++ 复制代码
string& operator+=(const char* str);             //重载+=操作符
string& operator+=(const char c);                //重载+=操作符
string& operator+=(const string& str);           //重载+=操作符
string& append(const char* s);                   //把字符串s连接到当前字符串结尾
string& append(const char* s,int n);             //把字符串前n个字符连接到当前字符串结尾
string& append(const string &s);                 //同operator+=(const string &str)
string& append(const string &s,int pos,int n);   //字符串s中从pos开始的n个字符连接到当前字符串结尾

使用实例:

c++ 复制代码
void test01()
{
	//1.+=操作符重载
	string str1 = "懒";
	str1 += "羊羊";
	cout << str1 << endl;//懒羊羊

	str1 += ':';
	cout << str1 << endl;//懒羊羊:

	string str2 = "是大厨";
	str1 += str2;
	cout << str1 << endl;//懒羊羊:是大厨

	//2.append函数
	string str3 = "LanYangyang ";
	str3.append("love ");
	cout << str3 << endl;//LanYangyang love

	str3.append("XiYangyang! ",10);
	cout << str3 << endl;//LanYangyang love XiYangyang

	//str3.append(str2);//LanYangyang love XiYangyang是大厨
	//str3.append(str2, 2);//LanYangyang love XiYangyang是大

	//从str2中截取,下标为1开始,截取2个,即 大厨
	str3.append(str2, 1, 2);//LanYangyang love XiYangyang大厨
}
5.string 查找和替换
  • 查找:查找指定字符串是否存在
  • 替换:在指定位置替换字符串

函数原型:

c++ 复制代码
int find(const string& str,int pos = 0)const;     //查找str第一次出现的位置,从pos开始查找
int find(const char* s,int pos = 0)const;         //查找s第一次出现的位置,从pos开始查找
int find(const char* s,int pos,int n)const;       //从pos位置查找s的前n个字符第一次出现的位置
int find(const char c,int pos = 0)const;          //查找字符c第一次出现的位置
int rfind(const string& str,int pos = npos)const; //查找str最后依次位置,从pos开始查找
int rfind(const char* s,int pos = npos)const;     //查找s最后一次出现的位置,从pos开始查找
int rfind(const char* s,int pos,int n)const;      //从pos查找s的前n个字符最后一次出现的位置
int rfind(const char c,int pos = 0)const;         //查找字符c最后一次出现的位置
string& replace(int pos,int n,const string& str); //替换从pos开始的n个字符为字符串str
string& replace(int pos,int n,const char* s);     //替换从pos开始的n个字符为字符串s

使用示例:

c++ 复制代码
//查找
void test01()
{
	//1.find。从前往后找第一次出现的位置
	string str1 = "abcdedef";
	int pos= str1.find("de");//3,下标从0开始,若没有返回-1
	cout << pos << endl;
	if (pos == -1)
	{
		cout << "没有找到字符串" << endl;
	}
	else
	{
		cout << "找到字符串,位置为:" << pos << endl;
	}
	//2.rfind,从后往前找,第一次出现的位置
	int pos1 = str1.rfind("de");//5
	cout << pos1 << endl;
}

//替换
void test02()
{
	string str1 = "abcdedef";
	str1.replace(1, 3, "lanyy");//从下标1到下标3的字符替换成新的字符串lanyy,
	//给定了5个,所以5个全部进入(将多少个字符替换成什么样的字符串)
	cout << str1 << endl;//alanyyedef
}
6.string 字符串比较

字符串之间的比较;比较方式:字符串比较是按照字符的 ASCII 码进行对比。等于 = 返回0,大于 > 返回 1,小于 < 返回 -1。函数原型:

c++ 复制代码
int compare(const string &s)cosnt; //与字符串s比较
int compare(cosnt char *s)const;   //与字符串s比较

使用示例:

c++ 复制代码
void test01()
{
	string str1 = "lanyy is dachu!";
	string str2 = "xiyangyang love lanyy!";
	if (str1.compare(str2) == 0)
	{
		cout << "两者相等" << endl;
	}
	else if (str1.compare(str2) == 1)
	{
		cout << "str1 > str2" << endl;
	}
	else
	{
		cout << "str1 < str2" << endl;
	}
}

一般用作比两个字符串是否相等。

7.string 字符存取

string中单个字符存取有两种方式:

c++ 复制代码
char& operator[](int n);   //通过[]方式获取字符
char& at(int n);           //通过at方法获取字符

使用示例:

c++ 复制代码
void test01()
{
	string str = "lanyangyang";

	//1.通过[]访问
	for (int i = 0; i < str.size(); i++)//size()是获取字符串长度的函数
	{
		cout << str[i] << " ";//读
	}
	cout << endl;
	//2.通过at访问
	for (int i = 0; i < str.size(); i++)
	{
		cout << str.at(i) << " ";//读
	}
	cout << endl;

	//修改
	str[0] = 'x';
	str.at(1) = 'i';
	cout << str << endl;
}
8.string 插入和删除

对string字符串进行插入和删除字符操作。函数原型:

c++ 复制代码
string& insert(int pos,const char* s);    //插入字符串
string& insert(int pos,const string& str);//插入字符串
string& insert(int pos,int n,char c);     //在指定位置插入n个字符c
string& erase(int pos,int n = npos);      //删除从pos开始的n个字符

使用示例:

c++ 复制代码
void test01()
{
	string str = "lanyangyang is chicken!";

	//插入
	str.insert(1, "xiyangyang ");//在下标为1的后面插入该字符串lxiyangyang anyangyang id chicken!
	cout << str << endl;

	//删除
	str.erase(1, 11);//从下标为1开始删除11个字符
	cout << str << endl;
}

插入和删除起始下标都是从0开始

9.string 字串

从字符串中获取想要的(指定的)字符串。函数原型:

c++ 复制代码
string substr(int pos=0;int n;)

使用示例:

c++ 复制代码
void test01()
{
	string str = "lanyangyang is chicken!";
	string subStr = str.substr(3, 8);//从下标3开始的8个字符,yangyang
	cout << subStr << endl;
}

void test02()
{
	//实际操作
	string email = "yangcun@163.com";
	//从邮件地址中获取用户名信息
	int pos = email.find('@');//查找@第一次出现的位置下标
	string userName = email.substr(0, pos);//获取0开的的pos个字符
	cout << userName << endl;
}
二、vector容器
1.vector容器基本概念

功能:vector数据结构和数组非常相似 ,也称为单端数组

vector与普通数组区别 :不同之处在于数组是静态空间,而vector可以动态扩展

动态扩展:不是在原空间之后接新的空间,而是重新开辟一块更大的空间,然后将原数据拷贝到新的空间,并释放原空间再进行相关操作

vector容器,前端封闭,后端开放,在后端进行操作。提供4个常用的函数:

  • v.begin():指向开始第一个元素
  • v.end():指向最后一个元素的下一个位置
  • v.rbegin():指向倒数第一个元素
  • v.rend():指向第一个元素的前一个位置

其他还会提供很多函数。vector容器的迭代器是支持随机访问的迭代器

2.vector构造函数

功能描述:创建一个vector容器。函数原型:

c++ 复制代码
vector<T> v;                //采用模板实现类实现,默认构造函数
vector(v.begin(),v.end());  //将v.begin(),v.end()区间的元素拷贝给本身
vector(n,elem);             //构造函数将n个elem拷贝给本身
vector(const vector &vec);  //拷贝构造函数

使用示例:

c++ 复制代码
void myPrint(vector<int>&v)
{
    //从容器开始到容器结束区间的数据
	for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;
}

//vector容器构造
void test01()
{
	vector<int> v1;//默认构造  无参构造
	for (int i = 0; i < 10; i++)
	{
		v1.push_back(i);//填入数据
	}
	myPrint(v1);

	//2.通过区间的方式进行构造
	vector<int>v2(v1.begin(), v1.end());//将begin到end区间内的值赋值给v2
	myPrint(v2);

	//3.n个elem的方式进行构造
	vector<int>v3(8, 7);//输入8个7
	myPrint(v3);

	//4.拷贝构造
	vector<int>v4(v3);
	myPrint(v4);
}

灵活使用

3.vector赋值操作

功能描述:给vector容器进行赋值;函数原型:

c++ 复制代码
vector& operator = (const vector &vec); //重载等号操作符
assign(beg,end);      //将beg,end区间中的数据拷贝赋值给本身
assign(n,elem);       //将n个elem拷贝赋值给本身

使用示例:

c++ 复制代码
void test01()
{
	vector<int>v1;
	for (int i = 0; i < 10; i++)
	{
		v1.push_back(i);
	}
	myPrint(v1);//0 1 2 3 4 5 6 7 8 9 

	//赋值opreator =
	vector<int>v2;
	v2 = v1;//直接等
	myPrint(v2);//0 1 2 3 4 5 6 7 8 9 

	//assign
	vector<int>v3;
	v3.assign(v1.begin(), v1.end());//前闭区间,后开区,将v1的begin到end区间的元素赋值给v3
	myPrint(v3);//0 1 2 3 4 5 6 7 8 9 

	//n个elem方式赋值
	vector<int>v4;
	v4.assign(8, 7);
	myPrint(v4);//7 7 7 7 7 7 7 7
}

vector赋值方式很简单,用 = 或者assign均可以

4.vector容量和大小

功能描述:对vector容器的容量和大小操作。函数原型:

c++ 复制代码
empty();       		//判断容器是否为空
capacity();    		//容器的容量
size();              //返回容器中当前元素的个数
resize(int num);     //重新指定容器的长度为num,若容器变长,则以默认值填充新位置
                     //若容器过短,则末尾超出容器长度的元素被删除
resize(int num,elem);//重新指定容器长度为num,若容器变长,则以elem的值填充新位置
                     //若容器过短,则末尾超出容器长度的元素被删除

使用示例:

c++ 复制代码
void test01()
{
	vector<int>v1;
	for (int i = 0; i < 10; i++)
	{
		v1.push_back(i);
	}
	myPrint(v1);

	if (v1.empty())//如果为真就说明为空,判断是否为空
	{
		cout << "v1为空" << endl;
	}
	else
	{
		cout << "v1不为空" << endl;
		cout << v1.capacity() << endl;//输出v1的容量,13
		cout << v1.size() << endl;//输出v1的大小(当前已有元素个数),10
	}
	//重新指定大小
	//v1.resize(15);//重新指定容量为15个,若指定比原来长,就会以默认值替补补上
	myPrint(v1);//0 1 2 3 4 5 6 7 8 9 0 0 0 0 0

	//指定默认填充的值
	v1.resize(15, 7);//指定默认替补的值为7,修改大小为15个
	myPrint(v1);//0 1 2 3 4 5 6 7 8 9 7 7 7 7 7

	//重新指定比原来短的容量,会删除原来多的
	v1.resize(7);
	myPrint(v1);//0 1 2 3 4 5 6
}

resize是对容器大小进行改变,这里大小是指容器内部元素的个数,容器的容量并未改变

5.vector插入和删除

对vector容器进行插入、删除操作,相关函数原型为:

c++ 复制代码
push_back(elem);						//尾部插入元素elem
pop_back();							    //删除最后一个元素
insert(const_iterator pos,elem);	      //迭代器指向位置pos插入元素elem
insert(const_iterator pos,int count,elem);//迭代器指向位置pos插入count个元素elem
erase(const_iterator pos);                //删除迭代器指向的元素
erase(const_iterator start,const_iterator end);//删除迭代器从start到end区间内的元素
clear();                                  //删除容器中的所有元素

使用示例:

c++ 复制代码
void test01()
{
	vector<int>v1;
	//先插入数据,尾插法
	v1.push_back(7);
	v1.push_back(8);
	v1.push_back(9);
	v1.push_back(6);
	v1.push_back(8);
	
	myPrint(v1);

	//尾删法
	v1.pop_back();//删除尾部的一个元素;7896

	//插入
	v1.insert(v1.begin(), 100);//第一个参数是迭代器,在begin的位置前插入100
	myPrint(v1);//100 7 8 9 6

	v1.insert(v1.begin(), 2, 200);//在指定的位置前插入2个200
	myPrint(v1);//200 200 100 7 8 9 6

	//删除
	v1.erase(v1.begin());//第一个参数也是迭代器,删除v1.begin指定位置的值
	myPrint(v1);//200 100 7 8 9 6

	//v1.erase(v1.begin(), v1.end());//删除区间begin到end之间的元素,类似清空
	v1.clear();
	myPrint(v1);//没有,已经删完了,只会输出一个换行
}
6.vector数据存取

对vector容器中的数据进行存取操作,函数原型为:

c++ 复制代码
at(int idx);      //返回索引idx位置的数据
operator[];   //返回索引idx位置的元素
front();   //返回第一个元素
back();   //返回最后一个元素

使用示例:

c++ 复制代码
void test01()
{
	vector<int>v1;
	for (int i = 0; i < 10; i++)
	{
		v1.push_back(i);
	}
	//利用[]访问元素
	for (int i = 0; i < v1.size(); i++)
	{
		cout << v1[i] << " ";
	}
	cout << endl;

	//利用at方式访问元素
	for (int i = 0; i < v1.size(); i++)
	{
		cout << v1.at(i) << " ";
	}
	cout << endl;

	//返回第一个元素,获取第一个元素
	cout << v1.front() << endl;//0
	//返回最后一个元素
	cout << v1.back() << endl;//9
}
7.vector互换容器

实现两个容器之间元素的互换。函数原型为:

c++ 复制代码
swap(vec);//将vec内的元素与本身的元素互换

使用示例:

c++ 复制代码
void test01()
{
	vector<int>v1;
	for (int i = 0; i < 10; i++)
	{
		v1.push_back(i);
	}
	cout << "交换前:" << endl;
	myPrint(v1);//0 1 2 3 4 5 6 7 8 9

	vector<int>v2;
	for (int i = 9; i >=0; i--)
	{
		v2.push_back(i);
	}
	myPrint(v2);//9 8 7 6 5 4 3 2 1 0
	
    //1.基本使用
	v1.swap(v2);
	cout << "交换后:" << endl;
	myPrint(v1);//9 8 7 6 5 4 3 2 1 0
	myPrint(v2);//0 1 2 3 4 5 6 7 8 9

	//2.实际使用
	//巧用swap可以收缩空间
	vector<int>v;
	for (int i = 0; i < 100000; i++)
	{
		v.push_back(i);
	}
	cout << v.capacity() << endl;//v的容量,138255
	cout << v.size() << endl;//v的当前元素个数,100000

	v.resize(3);//重新指定大小,大小(元素个数)
	cout << v.capacity() << endl;//v的容量,138255
	cout << v.size() << endl;//v的当前元素个数,3

	vector<int>(v).swap(v);//收缩内存
	//vector<int>(v)表示一个匿名对象,相当于调用了拷贝构造函数利用v创建了一个新的对象,这个新的对象没有名字(假设x)
	//这个匿名对象用v目前所用的个数来初始化自己,所以最开始大小和容量就是3,然后匿名对象指向了容器x(3,3)
	//然后调用swap(v),使用了容器之间的交换,所以x指向了原来v的大容量,v指向了x的小容量
	//当前行结束后,编译器发现这个是匿名对象,会将其马上释放
	cout << v.capacity() << endl;//v的容量,3
	cout << v.size() << endl;//v的当前元素个数,3
}

swap可以使两个容器互换,可以达到实用的收缩内存的效果

8.vector预留空间

减少vector在动态扩展容量时的扩展次数;函数原型为:

c++ 复制代码
reserve(int len);   //容器预留len个元素长度,预留位置不初始化,元素不可访问

使用示例:

c++ 复制代码
void test01()
{
	vector<int>v;

	//利用reserve来预留空间
	v.reserve(100000);
	int num = 0;
	int* p = NULL;
	for (int i = 0; i < 100000; i++)
	{
		v.push_back(i);

		if (p != &v[0])//若重新开辟就不会指向它的首地址
		{
			p = &v[0];//一旦发生改变就会重新开辟(动态扩展)
			num++;
		}
	}
	cout << num << endl;//30   ---.>  1
    //若没有reserve操作,就会发生30次动态扩展,但是一旦预留了空间,就不会频繁发生动态扩展,只会发生一次
}
三、deque容器
1.deque容器基本概念

deque容器相当于双端数组 ,除尾端外,也可以对头端进行插入删除操作。deque和vector的区别

  • vector对于头部的插入和删除效率低,数据量越大,效率越低;(需要把全部数据向后/前移动)
  • deque相对而言,对头部的插入和删除速度比vector要快;
  • vector访问元素时的速度会比deque快,这和两者内部实现有关

相关函数:

  • push_front(); 头部的插入
  • pop_front(); 头部的删除
  • push_back(); 尾部的插入
  • pop_back(); 尾部的删除

迭代器包含:d.begin() 和 d.end()

deque 内部工作原理 :deque 内部有个中控器 ,维护每段缓冲区 中的内容,缓冲区中存放真实数据,中控器维护的是每个缓冲区的地址(指针指向缓冲区),使得使用 deque 时像一片连续的内存空间。中间的缓冲区都是满的,但是两边(开头和结尾的缓冲区)会有空,插入就直接插入,若多了,就再开一个缓冲区,用新的指针维护就是

deque容器的迭代器也支持随机访问

c++ 复制代码
void myPrint(const deque<int>& d)//防止在内部出现写操作,可以加const限制
{
	//for (deque<int>::iterator it = d.begin(); it != d.end(); it++)//普通的迭代器iterator,可读可写
	for (deque<int>::const_iterator it = d.begin(); it != d.end(); it++)//添加const,只读不可写
	{
		//*it=100;//报错,添加了const修饰,只读不可以写(改)
		cout << *it << " ";
	}
	cout << endl;
}
2.deque构造函数

deque容器的构造,相关函数的原型:

c++ 复制代码
deque<T>deqT;			//默认构造形式
deque(beg,end);			//构造函数将[beg,end]区间中的元素拷贝给本身
deque(n,elem);			//构造函数将n个elem拷贝给本身
deque(const deque &deq); //拷贝构造函数

使用示例:

c++ 复制代码
void test01()
{
	deque<int>d1;
	for (int i = 0; i < 10; i++)
	{
		d1.push_back(i);
	}
	myPrint(d1);//0 1 2 3 4 5 6 7 8 9

	deque<int>d2(d1.begin(), d1.end());
	myPrint(d2);//0 1 2 3 4 5 6 7 8 9

	deque<int>d3(8, 7);//赋值8个7
	myPrint(d3);//7 7 7 7 7 7 7 7 

	deque<int>d4(d3);//拷贝构造,把d3拷贝给d4
	myPrint(d4);//7 7 7 7 7 7 7 7
}

deque容器和vector容器构造基本一致

3.deque赋值操作

赋值操作和vector容器赋值基本上一样,进行赋值。相关函数原型:

c++ 复制代码
deque& operator=(const deque &deq);//重载等号操作符,直接等
assign(beg,end); //将[beg,end]区间内的数据拷贝赋值给本身
assign(n,elem);//将n个elem拷贝赋值给本身

使用示例:

c++ 复制代码
void test01()
{
	deque<int>d1;
	for (int i = 0; i < 10; i++)
	{
		d1.push_back(i);
	}
	myPrint(d1);//0 1 2 3 4 5 6 7 8 9

	//1.等号赋值operator=
	deque<int>d2;
	d2 = d1;
	myPrint(d2);//0 1 2 3 4 5 6 7 8 9

	//2.assign赋值
	deque<int>d3;
	d3.assign(d1.begin(), d1.end());
	myPrint(d3);//0 1 2 3 4 5 6 7 8 9

	deque<int>d4;
	d4.assign(8, 7);
	myPrint(d4);//7 7 7 7 7 7 7 7 
}
4.deque大小操作

对deque容器的大小进行操作,相关函数的原型:

c++ 复制代码
deque.empty();          //判断容器是否为空
deque.size();		   //返回容器当前元素个数
deque.resize(num);      //重新指定容器的长度为num,若容器边长,则以默认值填充新位置
                        //若容器变短,则超出部分被删除
deque.resize(num,elem); //重新指定容器的长度为num,若容器边长,则以elem填充新位置
                        //若容器变短,则超出部分被删除

与vector相比,deque没有容量,只有元素的个数,因为deque的内部结构,若不够了,加一个缓冲区就是;使用示例:

c++ 复制代码
void test01()
{
	deque<int>d1;
	for (int i = 0; i < 10; i++)
	{
		d1.push_back(i);
	}
	myPrint(d1);

	if (d1.empty())//判断是否为空
	{
		cout << "为空!" << endl;
	}
	else
	{
		cout << "不为空!" << endl;
	}

	cout << d1.size() << endl;//返回d1的大小,10

	//d1.resize(15);//重新指定大小为15个
	//myPrint(d1);//0 1 2 3 4 5 6 7 8 9 0 0 0 0 0 

	d1.resize(15, 7);//重新指定大小为15,不够用7补上
	myPrint(d1);//0 1 2 3 4 5 6 7 8 9 7 7 7 7 7 
}

deque没有容量的概念

5.deque插入和删除

向deque容器中插入和删除数据。相关函数的原型为:

c++ 复制代码
//两端插入操作push/pop:
push_back(elem);   //在容器尾部插入一个数据
push_front(elem);  //在容器前端插入一个数据
pop_back();        //在容器位处删除一个数据
pop_front();       //在容器前端删除一个数据

//指定位置操作insert/clear/erase
insert(pos,elem);    //在pos位置插入一个elem元素的拷贝,返回新数据的位置
insert(pos,n,elem);  //在pos位置插入n个elem的数据,无返回值
insert(pos,beg,end); //在pos位置插入[beg,end]区间的数据,无返回值
clear();             //清空容器中的所有数据
erase(beg,end);      //删除[beg,end]区间内的数据,返回下一个数据的位置
erase(pos);          //删除pos位置的数据,返回下一个数据的位置

使用示例:

c++ 复制代码
void test01()
{
	deque<int>d1;

	//两端插入
	//尾插
	d1.push_back(6);
	d1.push_back(7);
	d1.push_back(8);
	d1.push_back(9);
	myPrint(d1);//6 7 8 9
	//头插
	d1.push_front(5);
	d1.push_front(4);
	d1.push_front(3);
	d1.push_front(2);
	d1.push_front(1);
	myPrint(d1);//1 2 3 4 5 6 7 8 9
	//尾删
	d1.pop_back();
	myPrint(d1);//1 2 3 4 5 6 7 8
	//头删
	d1.pop_front();
	myPrint(d1);//2 3 4 5 6 7 8

	//指定位置操作
	d1.insert(d1.begin(), 1);
	myPrint(d1);//1 2 3 4 5 6 7 8

	d1.insert(d1.begin(), 2, 0);
	myPrint(d1);//0 0 1 2 3 4 5 6 7 8

	deque<int>d2;
	d2.push_back(7);
	d2.push_back(7);
	d2.push_back(7);
	d2.push_back(7);
	d1.insert(d1.begin(), d2.begin(), d2.end());
	myPrint(d1);//7 7 7 7 0 0 1 2 3 4 5 6 7 8

	//删除
	deque<int>::iterator it = d1.begin();
	it++;
	//d1.erase(d1.begin())
	d1.erase(it);//7 7 7 0 0 1 2 3 4 5 6 7 8
	myPrint(d1);

	//按区间删除
	//d1.erase(d1.begin(), d1.end());
	deque<int>::iterator it1 = d1.begin();
	it1++;
	d1.erase(it1, it1 + 3);//7 0 1 2 3 4 5 6 7 8
	myPrint(d1);

	//清空:
	//d1.erase(d1.begin(), d1.end());
	d1.clear();

}

提供位置pos、beg、end一定要是迭代器

6.deque数据存取

对deque中数据的存取操作,相关函数的原型:

c++ 复制代码
at(int idx);      //返回索引idx所指的数据
operater[];       //返货索引idx所指的数据
front();          //返回容器中第一个数据元素
back();           //返回容器中最后一个数据元素

使用示例:

c++ 复制代码
void test01()
{
	deque<int>d1;
	for (int i = 0; i < 10; i++)
	{
		d1.push_back(i);
	}
	cout << d1.at(6) << endl;//6,这里的括号内的6和7是指下标6和7
	cout << d1[7] << endl;//7
	cout << d1.front() << endl;//0
	cout << d1.back() << endl;//9
}
7.deque排序

利用算法实现对deque容器进行排序,相关函数的原型:

c++ 复制代码
sort(iterator beg,iterator end);//对区间[beg,end]内的元素进行排序

使用示例:

c++ 复制代码
void test01()
{
	deque<int>d1;
	d1.push_back(8);
	d1.push_back(2);
	d1.push_back(6);
	d1.push_back(5);
	d1.push_front(9);
	d1.push_front(1);

	myPrint(d1);//1 9 8 2 6 5

	//排序
	sort(d1.begin(), d1.end());//默认升序排序
	myPrint(d1);//1 2 5 6 8 9
}

对于支持随机访问的迭代器,都可以利用sort算法直接对其进行排序,vector容器也可以用sort进行排序;但是在使用sort算法时要包含头文件

c++ 复制代码
#include<algorithm>
案例 -- 评委打分
1.案例描述:

有5名选手,选手ABCDE,10个评委分别对每一名选手打分,去除最高分、最低分,取平均分为最终选手评分;

2.实现思路(步骤):
  • 创建5名选手,放到vector容器中;vector的每个元素都是一个人Person,人包含名字(ABCDE)和最终打分
  • 遍历vector容器,取出来每一个选手,执行for循环,把名字存入,把10个评委的打分存到vector容器下的deque容器中;
  • 利用sort算法对deque算法进行排序,去除最高和最低分;
  • deque再次遍历求得总分;获取平均分
3.实现代码:
c++ 复制代码
#include<iostream>
using namespace std;
#include<vector>
#include<deque>
#include<algorithm>
#include<string>

class Person
{
public:
	Person(string name, int score)
	{
		this->m_Name = name;
		this->m_Score = score;
	}

	string m_Name;
	int m_Score;//平均分
};

void creatPerson(vector<Person>& v)
{
	string nameSeed = "ABCDE";
	for (int i = 0; i < 5; i++)
	{
		string name = "选手";
		name += nameSeed[i];

		int score = 0;//设置每个人的初始分数为0
		Person p(name, score);//有参构造,构造每个人

		//将创建的Person对象放入到容器中
		v.push_back(p);
	}
}

//打分
void setScore(vector<Person>& v)
{
	for (vector<Person>::iterator it = v.begin(); it != v.end(); it++)
	{
		deque<int>d;
		for (int i = 0; i < 10; i++)
		{
			//rand()%41是0-40的随机数,加50就是50-100的随机数
			int score = rand()%41+50;//50-100之间的随机数
			d.push_back(score);
		}
		cout << "选手:" << it->m_Name << " 打分:" << endl;
		for (deque<int>::iterator dit = d.begin(); dit != d.end(); dit++)
		{
			cout << *dit << " ";//输出每位选手的打分情况
		}
		cout << endl;
        
		//排序
		sort(d.begin(), d.end());

		//去除最高分
		d.pop_back();
		//去除最低分
		d.pop_front();

		//获取平均分
		int sum = 0;
		for (deque<int>::iterator dit = d.begin(); dit != d.end();dit++)
		{
			sum += *dit;
		}
		int avg = sum / d.size();

		it->m_Score = avg;//给每个人的平均分属性赋值
	}
}

void showScore(vector<Person>& p)//展示这个人的姓名以及获取的最终分数
{
	for (vector<Person>::iterator it = p.begin(); it != p.end(); it++)
	{
		cout << "姓名: " << it->m_Name << "  平均分:" << it->m_Score << endl;
	}
}
int main()
{
	//1.创建5个选手
	vector<Person>v;//存放选手的容器
	creatPerson(v);
	//测试
	//for (vector<Person>::iterator it = v.begin(); it != v.end(); it++)
	//{
		//cout << (*it).m_Name << (*it).m_Score << endl;
	//}
	
	//2.打分
	setScore(v);
	//3.显示最后得分
	showScore(v);

	system("pause");
	return 0;
}
相关推荐
蒸蒸yyyyzwd2 小时前
网络编程——threadpool.h学习笔记
笔记·学习
浪子不回头4152 小时前
SGLang学习笔记
人工智能·笔记·学习
王琦03182 小时前
Python 函数详解
开发语言·python
胡伯来了2 小时前
13. Python打包工具- setuptools
开发语言·python
小鸡吃米…2 小时前
Python 中的多层继承
开发语言·python
deng-c-f3 小时前
Linux C/C++ 学习日记(53):原子操作(二):实现shared_ptr
开发语言·c++·学习
wanghowie3 小时前
01.07 Java基础篇|函数式编程与语言新特性总览
java·开发语言·面试
Cricyta Sevina3 小时前
Java IO 基础理论知识笔记
java·开发语言·笔记
一个不知名程序员www3 小时前
算法学习入门---结构体和类(C++)
c++·算法