C++笔记九(STL:基础知识、string、vector、deque)

1.STL基础

1.1为了建立数据结构与算法的一套标准,诞生了STL。
STL(标准模板库)广义分为:容器、算法、迭代器。
容器与算法之间通过迭代器进行无缝连接。
STL 所有代码基本上都采用了类模板和函数模板。

1.2 STL六大组件,分别为:容器、算法、迭代器、仿函数、适配器(配接器)、空间配置器。
容器:各种数据结构,如:vector、list、deque、set、map等,用于存放数据。
算法:各种常用的算法,如:sort、find、copy、for_each等。
迭代器:扮演了容器与算法之间的胶合剂。
仿函数:行为类似函数,可作为算法的某种策略。
适配器:一种用来修饰容器或者仿函数或者迭代器接口的东西。
空间配置器:负责空间的配置与管理。

1.3 STL中容器、算法、迭代器
容器:置物之所也
STL容器就是将运用最广泛的一些数据结构实现出来。
常用的数据结构:数组、链表、树、栈、队列、集合、映射表等。
这些容器分为序列式容器与关联式容器两种:
序列式容器:强调值的排序,序列式容器中的每个元素均有固定的位置。
关联式容器:二叉树结构,各元素之间没有严格的物理上的顺序关系。

算法:问题之解法也
有限的步骤,解决逻辑或者数学上的问题,这一门学科我们叫做算法(Algorithms)。
算法分为:质变算法与非质变算法。
质变算法:是指运算过程中会改变区间内元素的内容。例如:拷贝、替换、删除等等。
非质变算法:是指运算过程中不会改变区间内的元素内容,例如:查找、计数、 遍历、寻找极值等。

迭代器:容器与算法之间的粘合剂
提供一种方法,使之能够依序访问某个容器是含的各个元素,而又无需暴露该容器的内部表达式。且每个容器都有自己专属的迭代器。
迭代器非常类似指针,初学阶段可以先理解成指针。
迭代器的种类:
在这里插入图片描述
常用的迭代器种类为双向迭代器和随机访问迭代器!

1.4 一个实例(vector容器)
vector容器可以理解为数组。
容器:vector
算法:for_each
迭代器:vector::iterator

#include<vector>
#include<algorithm>

void Show(int n)
{
    
    
	cout << n << endl;
}
void test()
{
    
    
	vector<int> v;
	v.push_back(10);
	v.push_back(20);
	v.push_back(30);

	//第一种遍历方式
	//vector<int>::iterator v_Begin = v.begin();	//v_Begin指向v的首元素
	//vector<int>::iterator v_End = v.end();	//v_End指向v的尾元素的后一位
	//while (v_Begin != v_End)
	//{
    
    
	//	cout << *v_Begin << endl;	//迭代器可以先简单的当作指针使用
	//	v_Begin++;
	//}

	//第二种遍历方式
	//for (vector<int>::iterator vBegin = v.begin(); vBegin != v.end(); vBegin++)
	//{
    
    
	//	cout << *vBegin << endl;
	//}

	//第三种遍历方式
	for_each(v.begin(), v.end(), Show);	//注意这里第三个参数是函数名
}

int main()
{
    
    
	test();
	return 0;
}

示例二:容器嵌套
//容器嵌套——这里使容器每一个元素都是容器

void test1()
{
    
    
	vector<int> v1;
	vector<int> v2;
	vector<int> v3;
	vector<int> v4;
	vector<int> v5;
	//存入数据
	for (int i = 0; i < 5; i++)
	{
    
    
		v1.push_back(i + 1);
		v2.push_back(i + 2);
		v3.push_back(i + 3);
		v4.push_back(i + 4);
		v5.push_back(i + 5);
	}
	//把容器放入大容器中
	vector<vector<int>> v;
	v.push_back(v1);
	v.push_back(v2);
	v.push_back(v3);
	v.push_back(v4);
	v.push_back(v5);
	//开始遍历
	for (vector<vector<int>>::iterator vit = v.begin(); vit != v.end(); vit++)
	{
    
    
		//其中这里V是大容器,所以*vit就是vector<int>
		for (vector<int>::iterator it = (*vit).begin(); it != (*vit).end(); it++)
		{
    
    
			cout << *it << " ";
		}
		cout << endl;
	}
}
int main()
{
    
    
	test1();
	return 0;
}

2.string容器

2.1基本概念:string是C++风格的字符串,本质上是一个类。

string与char *的区别:char *是一个指针,string是一个类,类内封装char *,由类管理这个字符串,是一个char *的容器。

特点:string类内部封装了很多成员方法,例如:查找find、删除delete、拷贝copy、替换replace、插入inset。string管理char*所分配的内存,不用担心复制越界和取值越界等问题,这些由类内部进行负责。

2.2string构造函数
构造函数原型:
string();                            //创建一个空的字符串 例如string str;
string(const char* s);         //使用字符串S初始化;
string(const string& str);   //使用一个string对象初始化另一个string对象
string(int n, char c);          //使用n个字符C初始化

void test()
{
    
    
	string s1;
	const char * c1 = "hello world!";
	string s2(c1);
	cout << "s2 = " << s2 << endl;
	string s3(s2);
	cout << "s3 = " << s3 << endl;
	string s4(5, 'a');
	cout << "s4 = " << s4 << endl;
}

int main()
{
    
    
	test();
	return 0;
}

2.3string的赋值操作
功能:给string字符串进行赋值
赋值函数的原型:
1> string& operator=(const char* s);   //char* 类型字符串 赋值给当前的字符串。
2> string& operator=(const string &s); //把字符串s赋值给当前的字符串。
3> string& operator=(char c);               //把字符赋值给当前的字符串。
4> string& assign(const char* s);          //把字符串s赋值给当前的字符串。
5> string& assign(const char* s, int n);  //把字符串s的前n个字符赋值给当前的字符串。 (一定是const char* s,不能是string类型)
6> string& assign(const string &s);        //把字符串s赋值给当前的字符串。
7> string& assign(int n, char c);             //把n个字符c赋值给当前的字符串。

void test1()
{
    
    
	string s1;
	s1 = "hello world!";
	string s2;
	s2 = s1;
	string s3;
	s3 = 'a';
	string s4;
	s4.assign("hello world!");
	string s5;
	s5.assign("hello world!", 5);
	string s6;
	s6.assign(s4);
	string s7;
	s7.assign(8, 's');

	cout << "s1:" << s1 << endl;
	cout << "s2:" << s2 << endl;
	cout << "s3:" << s3 << endl;
	cout << "s4:" << s4 << endl;
	cout << "s5:" << s5 << endl;
	cout << "s6:" << s6 << endl;
	cout << "s7:" << s7 << endl;
}

2.4string字符串拼接
功能:实现在字符串末尾拼接字符串
函数原型:
1> string& operator+=(const char* s);
//重载+=操作符。
2> string& operator+=(const string &s);
//重载+=操作符。
3> string& operator+=(const char c);
//重载+=操作符。
4> string& append(const char* s);
//把字符串s拼接到当前的字符串结尾。
5> string& append(const char* s, int n);
//把字符串s的前n个字符拼接到当前的字符串结尾。
6> string& append(const string &s);
//同operator+=(const string &s)
7> string& append(const string &s, int pos, int n);
//把字符串s从pos(pos从0开始,包括pos)开始的n个字符c拼接到当前的字符串结尾。

 void test1()
{
    
    
	string s1;
	s1 = "hello ";
	s1 += "world!";	//第一种
	cout << "s1:" << s1 << endl;
	s1 += '!';	//第二种
	cout << "s1:" << s1 << endl;
	string s2;
	s2 = "hello ";
	s1 += s2;	//第三种
	cout << "s1:" << s1 << endl;
	s1.append("world!");	//第四种
	cout << "s1:" << s1 << endl;
	s1.append("hello world!",6);	//第五种
	cout << "s1:" << s1 << endl;
	string s3;
	s3 = "world!";
	s1.append(s3);	//第六种
	cout << "s1:" << s1 << endl;
	s1.append(s2, 0, 4);	//第七种
	cout << "s1:" << s1 << endl;
}

2.5string的查找和替换
功能:
查找——查找指定字符串是否存在。找不到返回-1
替换——在指定的位置替换字符串。
函数原型:
1> int find(const string& str, int pos = 0) const;
//查找str第一次出现的位置,从pos开始查找。
2> int find(const char* s, int pos = 0) const;
//查找s第一次出现位置,从pos开始查找。
3> int find(const char* s, int pos, int n) const;
//从pos位置查找s的前n个字符第一次位置。
4> int find(const char c, int pos = 0) const;
//查找字符c第一次出现位置

注意:rfind与find的区别仅仅是从右向左与从左向右的区别

5> int rfind(const string& str, int pos = npos) const;
//查找str最后一次位置,从pos开始查找。
6> int rfind(const char* s, int pos = npos) const;
//查找s最后一次位置,从pos开始查找。
7> int rfind(const char* s, int pos, int n) const;
//从pos查找s的前n个字符最后一次出现的位置。
8> int rfind(const char c, int pos = 0) const;
//查找字符c最后一次出现位置。
9> string& replace(int pos, int n, const string& str);
//替换从pos开始n个字符为字符串str。
10> string& replace(int pos, int n, const char *s);
//替换从pos开始n个字符为字符串s。

void test2()
{
    
    
	string s("hello world! hello MrL!");
	string s1("hello");
	//第一种
	cout << s.find(s1) << endl;	//输出0
	cout << s.find(s1, 0) << endl;	//输出0
	cout << s.find(s1, 3) << endl;	//输出13
	//第二种
	cout << s.find("rld", 2) << endl;	//输出8
	//第三种
	cout << s.find("lleee", 0, 2) << endl;	//输出2
	//第四种
	cout << s.find('e', 5) << endl;	//输出14
	//第五种
	cout << s.rfind(s1) << endl;	//输出13
	//第六种
	cout << s.rfind("ll", 13) << endl;	//输出2
	//第七种
	cout << s.rfind("lleee", 13, 2) << endl;	//输出2
	//第八种
	cout << s.rfind('e') << endl;	//输出14
	//第九种
	cout << s.replace(12, 9, s1) << endl;	//输出hello world!helloL!
	//第十种
	cout << s.replace(12, 1, "abc") << endl;	//hello world!abchello MrL!
}

2.6string字符串比较
功能:字符串之间比较
注意:最大用处是判断两字符串是否相等!
比较方法:按照ascii码比较。=返回0;>返回正数;<返回负数。
函数原型:
int compare(const string& str) const; //与字符串str比较
int compare(const char *s) const; //与字符串s比较

void test()
{
    
    
    string s1("hello");
    string s2("helll");
    cout<<s1.compare(s2)<<endl;
    //不管长度都是从第一个开始比较,只要有不同便会判断出大小
    //若长度不一致,短的与长的前部分完全一致,那长的更大!
    cout<<s1.compare("zzz")<<endl;  //返回-18
}

2.7string字符串存取(读写
string中单个字符串有两种存取方式。
char& operator[] (int n);       //通过[]获取字符
char& at(int n);                      //通过at()获取字符

void test1()
{
    
    
    string s1("hello");
    cout<<"获取hello中第二个字符:"<<s1[1]<<endl;
    cout<<"获取hello中第三个字符:"<<s1.at(2)<<endl;
    s1[1]='x';
    cout<<"使用[]修改第二字符为‘x’"<<s1<<endl;
    s1.at(2)='y';
    cout<<"使用at()修改第三字符为‘y’"<<s1<<endl;
} 

2.8字符串插入和删除
功能:对字符串进行插入和删除操作
函数原型:
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个字符

void test2()
{
    
    
    string s("hello");
    cout<<s<<endl;
    s.insert(3, "haha");
    cout<<s<<endl;
    string s1("xyz");
    cout<<s.insert(1,s1)<<endl;
    cout<<s.insert(0,5,'l')<<endl;
    cout<<s.erase(1,5)<<endl;
}

2.9子串获取
功能:从字符串中获取想要的子串
函数原型:
string substr(int pos = 0, int n = npos);
//返回从pos开始的n个字符

void test3()
{
    
    
    string s("hello world");
    cout<<s.substr(6,5)<<endl;
}

3.vector容器

3.1基本概念
功能:vector数据结构与数组很相似,也称为单端数组。
与数组区别:数组是静态的,但vector可以动态扩展。
动态扩展:不是在原空间后续接空间,而是直接找个更大的空间,把原数据拷贝到新空间中,最后释放原空间。
vector的迭代器是支持随机访问的迭代器。

3.2vector的构造函数
功能:创建vector容器
函数原型:
1> vector < T > v;
//使用类模板实现,默认构造函数。
2> vector(v.begin(),v.end());
//将v[begin(),vend())区间中的元素拷贝给本身。
3> vector(n, elem);
//构造函数将n个elem拷贝给本身。
4> vector(const vector &vec);
//拷贝构造函数。

void VecPrintf(vector<int> &v)
{
    
    
	for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
	{
    
    
		cout << *it << "\t";
	}
	cout << endl;
}

void test3()
{
    
    
	vector<int> v;	//默认构造函数
	for (int i = 0; i < 10; i++)
	{
    
    
		v.push_back(i);
	}
	VecPrintf(v);
	vector<int> v1(v.begin(), v.end());	//使用区间构造
	VecPrintf(v1);
	vector<int> v2(10, 100);	//10个100
	VecPrintf(v2);
	vector<int> v3(v2);	//拷贝构造
	VecPrintf(v3);
}

3.3vector赋值操作
功能:给vector容器进行赋值
函数原型:
1> vector& operator=(const vector &vec); //重载等号操作符
2> assign(v.beg, v.end); //将v的[beg, end)区间中的数据拷贝赋值给本身
3> assign(n, elem); //将n个elem拷贝赋值给本身

void test4()
{
    
    
	vector<int> v;
	for (int i = 0; i < 10; i++)
	{
    
    
		v.push_back(i);
	}
	vector<int> v1;
	v1 = v;	//重载等号操作符
	VecPrintf(v1);	//VecPrintf函数前面一个示例中有
	vector<int> v2;
	v2.assign(v.begin(), v.end());	//使用区间
	VecPrintf(v2);
	vector<int> v3;
	v3.assign(10, 100);	//10个100
	VecPrintf(v3);
}

3.4vector容量和大小
功能:对vector容器的容量和大小操作。
函数原型:
1> bool empty(); //判断容器是否为空。空返回真。
2> capacity(); //容器的容量。容量大于等于大小
3> size(); //返回容器中元素的个数。
4>void resize(int num); //重新指定容器的长度num,若容器变长,则以默认值0填充新位置,如果容器变短,则末尾超出容器长度的元素被删除。
5> resize(int num, elem); //重新指定容器的长度num,若容器变长,则以elem值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除。

void test5()
{
    
    
	vector<int> v1;
	cout << v1.empty() << endl;	//返回1
	vector<int> v2;
	for (int i = 0; i < 10; i++)
	{
    
    
		v2.push_back(i);
	}
	cout << v2.empty() << endl;	//返回0
	cout << v2.capacity() << endl;	//返回13(容量)
	cout << v2.size() << endl;	//返回10(元素个数)
	v2.resize(6);
	cout << v2.size() << endl;	//返回6(元素个数)
	cout << v2.capacity() << endl;	//返回13(容量)
	v2.resize(15, 10);
	cout << v2.size() << endl;	//返回15(元素个数)
	cout << v2.capacity() << endl;	//返回19(容量)
}

3.5vector插入和删除
功能:对vector容器进行插入和删除操作。
函数原型:
1> push_back(ele);
//在尾部插入元素ele。
2> pop_back();
//删除最后一个元素。
3> insert(const_iterator pos, ele);
//在迭代器指向位置pos插入元素ele。
4> insert(const_iterator pos, int count, ele);
//在迭代器指向位置pos插入count个元素ele。
5> erase(const_iterator pos);
//删除迭代器pos指向的元素。
6> erase(const_iterator start, const_iterator end);
//删除迭代器start与end之间的所有元素。(左闭右开)
7> clear();
//删除容器中所有元素。

void test6()
{
    
    
	vector<int> v;
	for (int i = 0; i < 10; i++)
	{
    
    
		v.push_back(i);	
	}
	cout << "使用push_back插入0到9:";
	VecPrintf(v);
	v.pop_back();	
	cout << "使用pop_back删除最后一个元素:";
	VecPrintf(v);
	v.insert(v.begin(), 100);
	cout << "使用insert插入100:";
	VecPrintf(v);
	v.insert(v.begin(), 2, 1000);
	cout << "使用insert插入2个1000:";
	VecPrintf(v);
	v.erase(v.begin());
	cout << "使用erase删除第一个元素:";
	VecPrintf(v);
	vector<int>::iterator it = v.begin();
	it++;
	v.erase(v.begin(), it);
	cout << "使用erase删除第一个元素:";
	VecPrintf(v);
	v.clear();
	cout << "清空!" << endl;
	cout << "size:" << v.size() << endl;
}

3.6vector数据存取(读写)
功能:对vector中的数据进行存取操作。
函数原型:(四个都可以进行读写操作)
1> at(int idx); //返回索引idx所指的数据。
2> operator[]; //返回索引idx所指的数据。
3> front(); //返回容器中第一个数据元素。
4> back(); //返回容器中最后一个数据元素。

void test4()
{
    
    
    vector<int> v;
    for(int i = 0; i < 5; i++)
    {
    
    
        v.push_back(i);
    }
    cout<<"第3个元素是:"<<v.at(2)<<endl;
    cout<<"第4个元素是:"<<v[3]<<endl;
    cout<<"第一个元素是:"<<v.front()<<endl;
    cout<<"最后一个元素是:"<<v.back()<<endl;
    v[2] = 10;
    cout<<v[2]<<endl;
    v.at(2) = 100;
    cout<<v[2]<<endl;
    v.front()=1;
    cout<<v[0]<<endl;
    v.back()=0;
    cout<<v.at(4)<<endl;
}

3.7vector互换容器
功能:实现两个容器内元素进行互换。
函数原型:swap(vec); //将vec中的元素与自身元素互换。

void VecPrintf(vector<int> v)
{
    
    
    for(vector<int>::iterator it = v.begin(); it != v.end(); it++)
    {
    
    
        cout<<*it<<"\t";
    }
    cout<<endl;
}
void test5()
{
    
    
    vector<int> v1(10,5);
    vector<int> v2(8,8);
    cout<<"v1:";
    VecPrintf(v1);
    cout<<"v2:";
    VecPrintf(v2);
    v1.swap(v2);
    cout<<"交换后!"<<endl;
    cout<<"v1:";
    VecPrintf(v1);
    cout<<"v2:";
    VecPrintf(v2);
}

实际作用:通过swap函数以实现收缩内存的效果。当我们创建一个匿名对象,通过swap把匿名对象所指空间与自身所指空间互换(指针交换)。然后自身的内存变缩小,最后匿名对象被释放,空间也被释放。

3.8vector预留空间
功能:减少vector在动态扩展容量时的扩展次数。
函数原型:
1> reserve(int len); //容器预留len个元素长度,预留位置不初始化,元素不可访问。

void test8()
{
    
    
    vector<int> v;
    v.reserve(10000);
    int num = 0;  //用于记录开辟空间的次数
    int *ptr = NULL;
    for(int i = 0; i<10000; i++)
    {
    
    
        v.push_back(i);
        if(ptr != &v[0])    //只要指针ptr的指向改变那就证明又开辟一次空间
        {
    
    
            ptr = &v[0];
            num++;
        }
    }
    cout<<num<<endl;    //不加reserve函数,返回15,加上返回1
}

4.deque容器

4.1deque容器基本概念
功能:双端数组,可以在头端进行插入删除操作

deque与vector的区别:
1> vector进行头端插入删除操作效率低,而且数据量越大效率越低。
2> deque相对来说,头端进行插入删除速度比vector快。
3> vector访问元素时速度比deque更快,这与两者内部实现有关。

deque内部实现原理:
deque内部有个中控器,维护每段缓冲区中的内容,缓冲区是存放真实数据的地方,中控器保存了每一段缓冲区的地址,由此看起来像一片连续的空间。
在这里插入图片描述
4.2deque的构造函数
功能:deque容器构造。
函数原型:
1> deque deqT; //默认构造形式。
2> deque(beg, end); //构造函数将[beg,end)区间中的元素拷贝给本身。
3> deque(n, elem); //构造函数将n个elem拷贝给本身。
4> deque(const deque &deq); //拷贝构造函数。

void DeqPrintf(const deque<int> &d)
{
    
    
	//for (deque<int>::iterator it = d.begin(); it != d.end(); it++)//迭代器it可读可写,而这里d我们要求是只读的
	for (deque<int>::const_iterator it = d.begin(); it != d.end(); it++)
	{
    
    
		//*it = 10;	//迭代器换成const_iterator后只读不可写
		cout << *it << "\t";
	}
	cout << endl;
 }

void test7()
{
    
    
	deque<int> d1;	//默认构造函数
	for (int i = 0; i < 5; i++)
	{
    
    
		d1.push_back(i);
	}
	cout << "d1:";
	DeqPrintf(d1);
	deque<int> d2(d1.begin(), d1.end());	//使用区间方式构造
	cout << "d2:";
	DeqPrintf(d2);
	deque<int> d3(5, 10);	//5个10
	cout << "d3:";
	DeqPrintf(d3);
	deque<int>d4(d3);	//拷贝构造函数
	cout << "d4:";
	DeqPrintf(d4);
}

4.3 deque赋值操作
功能描述:
给deque容器进行赋值
函数原型:
deque& operator=(const deque &deq); //重载等号操作符。
assign(beg, end); //将[beg, end)区间中的数据拷贝赋值给本身。
assign(n,elem); //将n个elem拷贝赋值给本身。

void test8()
{
    
    
	deque<int> d(5, 8);
	deque<int> d1;
	d1 = d;	//等号赋值
	DeqPrintf(d1);	//4.2实例中有DeqPrintf()函数的实现
	deque<int> d2;
	d2.assign(d.begin(), d.end());	//assign加区间
	DeqPrintf(d2);
	deque<int> d3;
	d3.assign(8, 8);	//重载assign
	DeqPrintf(d3);
}

4.4deque大小操作
功能:对deque容器的大小进行操作。(相比vector来说没有容量这个概念,deque可以无限扩充)
函数原型:
1> bool empty(); //判断容器是否为空。
2> int size(); //返回容器中元素个数。
3> void resize(num); //重新指定容器长度为num,若变长则以默认值0填充,若变短,则末尾超出部分删除。
4> void resize(num, elem); //同上,只不过不是用默认值填充而是用指定的elem。

void test9()
{
    
    
	deque<int> d(5, 8);
	if (d.empty())
	{
    
    
		cout << "d为空!" << endl;
	}
	else
	{
    
    
		cout << "d非空!" << endl;
	}
	cout << "d的大小:" << d.size() << endl;
	cout << "重置d的大小!" << endl;
	d.resize(10);
	cout << "d的大小:" << d.size() << endl;
	DeqPrintf(d);
	d.resize(12,8);
	cout << "d的大小:" << d.size() << endl;
	DeqPrintf(d);
}

4.5 deque插入和删除
功能:向deque容器中插入和删除数据

函数原型:
两端的插入操作
1> push_back(elem); //在容器尾部添加一个数据。
2> push_front(elem); //在容器头部插入一个数据。
3> pop_back(); //删除容器最后一个数据。
4> pop_front(); //删除容器第一个数据。

指定位置操作
5> insert(pos,elem); //在迭代器pos位置插入一个elem元素的拷贝,返回新元素的位置(返回迭代器,指向新元素)。
6> insert(pos, n, elem); //在pos位置插入n个elem数据,返回迭代器。
7> insert(pos, beg, end); //在pos位置插入[beg,end)区间的数据,返回迭代器。
8> clear(); //清空容器中所有数据。
9> erase(beg, end); //删除[beg, end)区间的数据,返回下一个数据的位置(返回迭代器)。
10> erase(pos); //删除pos位置的数据,返回下一个数据的位置(返回迭代器)。

void test10()
{
    
    
	deque<int> d(3, 8);
	DeqPrintf(d);	//输出8  8  8
	for (int i = 0; i < 3; i++)
	{
    
    
		d.push_back(i);
		d.push_front(i);
	}
	DeqPrintf(d);	//输出2 1 0 8 8 8 0 1 2
	cout << "删除最后一个元素!" << endl;
	d.pop_back();
	DeqPrintf(d);	//输出2 1 0 8 8 8 0 1
	cout << "删除第一个元素!" << endl;
	d.pop_front();
	DeqPrintf(d);	//输出1 0 8 8 8 0 1
	//insert
	d.insert(d.begin(), 10);
	cout << "容器最前面插入10:";
	DeqPrintf(d);
	cout<<*(d.insert(d.end(), 3, 10));
	cout << "容器最后面插入三个10:";
	DeqPrintf(d);
	d.insert(d.begin(), d.begin(), d.end());
	cout << "容器最前面插入自身所有元素:";
	DeqPrintf(d);
	//erase与clear
	d.erase(d.begin());
	cout << "将容器最前面的元素删除:";
	DeqPrintf(d);
	d.clear();
	cout << "清空!" << endl;
	cout << "大小:" << d.size() << endl;
}

4.6deque数据存取(读写)
功能:对deque中的数据进行存取操作。
函数原型:
1> at(int idx); //返回索引idx所指的数据。
2> operator[]; //返回索引idx所有的数据。
3> front(); //返回容器中第一个数据元素。
4> back(); //返回容器中最后一个数据元素。

void test11()
{
    
    
	deque<int> d(3, 8);
	cout << "d:";
	DeqPrintf(d);
	cout << "第二个元素是:" << d.at(1) << endl;
	cout << "把第三个元素改为0!" << endl;
	d[2] = 0;
	DeqPrintf(d);
	cout << "第一个元素是:" << d.front() << endl;
	cout << "把第三个元素改为10!" << endl;
	d.back() = 10;
	DeqPrintf(d);
}

4.7deque排序
功能:利用算法以实现对deque容器的排序。
算法:(对于所有支持随机迭代器的容器都可以使用sort进行排序)
1> sort(iterator beg, iterator end); //对beg和end之间的元素进行排序。

void test12()
{
    
    
	deque<int> d;
	for (int i = 0; i < 10; i++)
	{
    
    
		d.push_back(rand());	//rand()函数产生随机数
	}
	DeqPrintf(d);
	sort(d.begin(),d.end());	//从小到大
	DeqPrintf(d);
}

5.案例——评委打分

5.1 案例描述
有5名选手ABCDEF,10个评委分别对每一位选手进行打分,去除最高分以及最低分,取平均分。

5.2实现步骤
1> 创建选手对象,用vector容器存储
2> 使用deque存放分数,计算平均值,更新对象的成员变量
3> 显示所有选手信息

5.3实现代码

class Person
{
    
    
public:
	Person(string name, int sorce) :m_name(name), m_sorce(sorce){
    
    }
	string m_name;	//姓名
	int m_sorce;	//平均分
};
//构造选手对象,并存入vector中
void CreatPer(vector<Person> &v)
{
    
    
	for (int i = 0; i < 5; i++)
	{
    
    
		string partname = "ABCDE";
		string name = "player ";
		name += partname[i];	//获取姓名
		int sorce = 0;
		Person p(name, sorce);	
		v.push_back(p);
	}
}
//计算平均分数,更新m_sorce
void AverageSorce(vector<Person> &v)
{
    
    
	for (vector<Person>::iterator it = v.begin(); it != v.end(); it++)
	{
    
    
		//创建deque容器存放分数
		deque<int> d;
		for (int i = 0; i < 10; i++)	//十个评委评分
		{
    
    
			d.push_back(rand() % 40 + 60);	//所有分数在60~100,并记录
		}
		//排序,并去掉最大值和最小值
		sort(d.begin(), d.end());
		d.pop_back();
		d.pop_front();
		//获取平均分,更新m_sorce
		int total = 0;	//记录去最大最小值后的总分
		int aver = 0;	//记录平均分
		for (deque<int>::iterator dit = d.begin(); dit != d.end(); dit++)
		{
    
    
			total += *dit;
		}
		aver = total / d.size();	//获取平均值
		it->m_sorce = aver;		//更新数据
	}
}
//显示所有选手信息
void Show(vector<Person> &v)
{
    
    
	for (vector<Person>::iterator vit = v.begin(); vit != v.end(); vit++)
	{
    
    
		cout << "姓名:" << vit->m_name << "  均分:" << vit->m_sorce << endl;
	}
}
void test13()
{
    
    
	//第一步,创建选手对象,用vector容器存储
	vector<Person> v;
	CreatPer(v);
	//第二步,使用deque存放分数,计算平均值,更新对象的成员变量
	AverageSorce(v);
	//第三步,显示所有选手信息
	Show(v);
}

int main()
{
    
    
	test13();
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_45884870/article/details/111112383