STL常用容器

string容器

string基本概念

本质:string是C++风格的字符串,而string本质上是一个类
string和char * 区别:
char*是一个指针
string是一个类,类内部封装了char*,管理这个字符串,是一个char*型的容器。
特点:string类内部封装了很多成员方法。
例如:查找find,拷贝copy,删除delete替换replace,插入insert
string管理char*所分配的内存,不用担心复制越界和取值越界等,由类内部进行负责。

string构造函数:


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


总结:string的多种构造方式没有可比性,灵活使用即可

string的赋值操作 

功能描述:给string字符串进行赋值
赋值的函数原型:
string& operator=(const char * s);//char *类型字符串 赋值给当前的字符串
string& operator=(const string &s);//把字符串s赋给当前的字符串
string& operator=(char c);、、把字符赋值给当前的字符串
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赋给当前字符串

 总结:string的赋值方式很多,operator=这种方式是比较实用的

string字符串拼接操作

 功能描述:实现在字符串末尾拼接字符串
函数原型: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);//把字符串s的前n个字符连接到当前字符串结尾
 string& append(const string &s);//同operator+=(const string &str)
  string& append(const string &s,int pos,int n);//把字符串s中从pos开始的n个字符连接到当前字符串结尾

string查找和替换

功能描述:
查找:查找指定字符串是否存在
替换:在指定的位置替换字符串
函数原型: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& repalce(int pos,int n,const char *s);//替换从POS开始的n个字符为字符串s

string字符串比较

功能描述:字符串之间的比较
* 比较方式:字符串比较是按字符的ascll码进行对比
* =返回0
* >返回1
* <返回-1
* 函数原型:int compare(const string &s)const;//与字符串s比较
                     int compare(const char *s)const;//与字符串s比较

 总结:字符串的对比主要用于判断相不相等,判断谁大谁小意义不大!

string字符存取

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

总结:string字符串中单个字符存取两种方式,利用[]或at。

string字符串的插入和删除

功能描述:对string字符串进行插入和删除字符操作
* 函数原型:
* 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=pos);//删除从POS开始的n个字符

 总结:插入和删除的起始下标都是从0开始。

string子串获取:


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


总结:灵活的运用求子串功能,可以在实际开发中获得有效的数据

vector容器

vector容器基本概念:


* 功能vector数据结构与数组非常相似,也称为单端数组
* vector与普通数组区别:不同之处在于数组是静态空间,而vector可以动态扩展
* 动态扩展:并不是在原空军之后续接新空间,而是找更大的内存空间,然后将原数据拷贝新空间,释放原空间


vector容器的迭代器是支持随机访问的迭代器

 vector构造函数

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


总结:vector的多种构造方式没有可比性,灵活使用即可

vector容器赋值操作 

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

vector容器容量和大小


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

vector容器的插入和删除

 功能描述:对vector容器进行插入,删除操作
函数原型:push_back(ele); 尾部插入元素ele
pop_back();删除最后一个元素
insert(const_iterator pos,ele); 迭代器指向位置POS插入元素ele
insert(const_iterator pos,int count,ele);代器指向位置POS插入count个元素ele
erase(const_iterator pos);删除迭代器指向的元素
clear(); 删除容器中的所有元素
erase(const_iterator start,const_iterator end);删除迭代器从start到end之间的元素

 vector数据存取


* 功能描述:对vector中的数据的存取操作
* 函数原型:
* at(int idx); 返回索引idx所指的数据;
* operator[]; 返回索引idx所指的数据;
* front(); 返回容器中第一个数据元素
* back(); 返回容器中最后一个数据元素

 vector容器互换容器

功能描述:实现两个容器内元素进行互换
* 函数原型:swap(vec);将vec与本身的元素互换

vector<int>(v2).swap(v2);原理:

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

vector容器预留空间

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

总结:如果数据量较大,可以一开始利用reserve预留空间

deque容器

deque容器基本概念:功能:双端数组,可以对头端进行插入删除操作
deque与vector区别:
vector对于头部的插入删除效率低,数据量越大,效率越低
deque相对而言,对头部的插入删除速度会比vector快
vector访问元素时的速度会比deque快,这和两者内部实现有关

deque工作原理:
deuqe内部有个中控器,维护每段缓冲区中的内容,缓冲区中存放真实数据中控器维护的是每个缓冲区的地址,使得使用deque时像一片连续的内存空间

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

总结:deque容器与vector容器构造的方式基本一样,灵活使用即可。

deque赋值操作 

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

 总结:跟vector赋值操作也类似,需要熟练掌握。

deque大小操作:


* 功能描述:对deque容器的大小进行操作
* 函数原型
:deque.empty();//判断容器是否为空
* deque.size() //返回容器中元素的个数
* deque.resize(num);//重新指定容器的长度为num,若变长,则以默认值填充新位置。如果容器变短,则末尾超过容器的长度将被删除。
*deque.resize(num,elem);//重新指定容器的长度为num,若变长,则以elem值填充新位置。如果容器变短,则末尾超过容器的长度将被删除。
deque没有容量限制

 deque容器插入和删除

 功能描述:向deque容器中插入和删除数据
* 函数原型:
* 两端插入操作:
* push_back(elem);//在容器尾部添加一个数据
* push_front(elem);//在容器头部插入一个数据
* pop_back();//删除容器最后一个数据
* pop_front(); //删除容器第一个数据
指定位置操作:
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位置的数据,返回下一个数据的位置。

总结:插入和删除提供的位置是迭代器

deque中的数据存取

功能描述:对deque中的数据的存取操作
* 函数原型:at(int idx);//返回索引idx所指的数据
* operator[];//返回索引idx所指的数据
* front();//返回容器中第一个数据元素
* back();//返回容器中最后一个数据元素


总结:除了用迭代器获取deque容器中元素,[]和at也可以

deque容器中的排序 

 功能描述:利用算法实现对deque容器进行排序
* 算法:sort(iterator beg,iterator end);//对beg和end区间内元素进行排序

总结:默认排序规则 从小到大 对于支持随机访问的迭代器的容器,都可以利用sort算法直接对其进行排序 同vector一样

案例--评委打分

#include <iostream>
#include <deque>
#include <vector>
#include <algorithm>
#include <ctime>
using namespace std;
class person {
public:
	person(string name,double score) {
		m_name=name;
		m_score = score;
	}
	string m_name;
	double m_score;
};
void createperson(vector<person>&v) {
	string nameperson= "ABCDE";
	for (int i = 0;i<5;i++) {
		string name = "选手";
		name += nameperson[i];
		double score = 0;
		person p(name, score);
		v.push_back(p);		
	}
}
void setscore(vector<person>&v) {
	cout<<"评委打分:" << endl;
	for (vector<person>::iterator it = v.begin();it!=v.end();it++) {
		deque<double> d;
		cout << (*it).m_name<<" ";
		double score = 0, sum = 0;
		for (int i = 0; i < 10; i++) {
			score = rand() % 40 + 60;
			d.push_back(score);
			cout << score<<" ";
		}
		sort(d.begin(), d.end());
		d.pop_back();
		d.pop_front();
		for (deque<double>::iterator it = d.begin(); it != d.end(); it++) {
			sum += (*it);
		}
		(*it).m_score = sum /d.size();
		cout << endl;
	}
}
void showscore(vector<person>&p) {
	cout<<"按规则折算后为 :"<< endl;
	for (vector<person>::iterator it = p.begin(); it !=p.end(); it++) {
		cout<<(*it).m_name<<" : "<< (*it).m_score << endl;
	}
}
int main() {
	srand((unsigned int)time(NULL));
	vector<person> v;
	createperson(v);
	setscore(v);
	showscore(v);
	return 0;
}

stack容器

 功能描述:栈容器常用的对外接口
构造函数:stack<T> stk;//stack 采用模板类实现, stack对象的默认构造形式
stack(const stack &stk); //拷贝构造函数 赋值操作:
 stack& operator=(const stack &stk);//重载等号操作符
数据存取:
 push(elem);//向栈顶添加元素
 pop(); //从栈顶移除第一个元素
top();//返回栈顶元素
大小操作:
empty();判断堆栈是否为空
 size(); 返回栈的大小

 例子:

queue容器

queue基本概念


 概念:queue是一种先进先出的数据结构,它有两个出口。
队列容器允许从一端新增元素,从另一端移除元素
队列中只有队头和队尾才可以被外界使用,因此队列不允许有遍历行为。
队列中进数据称为--入队
队列中出数据称为--出队

 queue容器常用接口

功能描述:栈容器常用的对外接口
* 构造函数:queue<T> que;//queue采用模板类实现,queue对象的默认构造形式
* queue(const queue &que);//拷贝构造函数
* 赋值操作:queue& operator=(const queue &que);//重载等号操作符
* 数据存取:push(elem);//往队尾添加元素
* pop();//往队头移除第一个元素
* back();//返回最后一个元素
* front();//返回第一个元素
* 大小操作:
empty();//判断堆栈是否为空
* size();//返回栈的大小*/ 

 总结:

入栈:push

出栈:pop

大小:size

头部:front

尾部:back

判断是否为空:empty

list容器

list基本概念

 功能:将数据进行链式存储
* 链表是一种物理存储单元上非连续的存储结构,数据元素的逻辑顺序是通过链表中的指针链接实现的。
* 链表的组成:链表由一系列结点组成
* 结点的组成:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域
* STL中的链表是一个双向循环链表

由于链表的存储方式并不是连续的内存空间,因此链表list中的迭代器只支持前移和后移,属于双向迭代器。
list的优点:采用动态储存分配,不会造成内存浪费和溢出
链表执行插入和删除操作十分方便,修改指针即可,不需要移动大量元素。
list的缺点:
链表灵活,但是空间(指针域)和时间(遍历额外耗费较大)
list有一个重要的性质,插入操作和删除操作都不会造成原有list迭代器的失效,这在vector是不成立的。

总结:STL中List和vector是两个最常用的容器,各有优缺点。

list容器构造函数

功能描述:创建list容器
* 函数原型:list<T> lst; //list采用模板类实现,对象的默认构造形式
* list(beg,end); //构造函数将[beg,end]区间中的元素拷贝给本身
* list(n,elem); //构造函数将n个elem拷贝给本身
* list(const list &list); //拷贝构造函数

总结:list构造方式同其他几个STL常用容器,熟练掌握即可。

list赋值和交换

功能描述:给list容器进行赋值,以及交换list容器。
* 函数原型:
* assign(beg,end); //将[beg,end]区间中的数据拷贝赋值给本身。
* assign(n,elem); //将n个elem拷贝赋值给本身。
* list& operator=(const list &lst); //重载等号操作符
swap(lst); //将lst与本身的元素互换


总结:list赋值和交换操作能够灵活运用即可。

list容器大小操作

功能描述:对list容器的大小进行操作
* 函数原型
:list.empty();//判断容器是否为空
* list.size() //返回容器中元素的个数
* list.resize(num);//重新指定容器的长度为num,若变长,则以默认值填充新位置。如果容器变短,则末尾超过容器的长度将被删除。
*list.resize(num,elem);//重新指定容器的长度为num,若变长,则以elem值填充新位置。如果容器变短,则末尾超过容器的长度将被删除

 总结:

判断是否为空:empty

重新指定大小:resize

容器个数:size

list容器的插入和删除

功能描述:对list容器进行数据的插入和删除
* 函数原型
:push_back(elem);//在容器尾部加入一个元素
* pop_back();//删除容器中最后一个元素
* push_front(elem); //在容器开头插入一个元素
* pop_front();//从容器开头移除第一个元素
* 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位置的数据,返回下一个数据的位置。
 * remove(elem);//删除容器中所有与elem值匹配的元素。

list容器数据存取

功能描述:对list容器中数据进行存取
* 函数原型:front();//返回第一个元素。
* back(); //返回最后一个元素。

   总结:不可以用at方式访问list中的元素,不可以用[]访问list容器中的元素。
   原因是:list本质链表,不是用连续性空间存储数据,迭代器也是不支持随机访问的;

list容器-反转和排序

功能描述:将容器中的元素反转,以及将容器中的数据进行排序。
函数原型:
reverse();//反转链表
sort();//链表排序

总结:反转:reverse      排序sort(成员函数)

list排序案例:

 案例描述:将Person自定义数据类型进行排序,person中属性有姓名,年龄,身高
 排序规则:按照年龄进行升序,如果年龄相同按照身高进行降序。

总结:对于自定义数据类型,必须要指定排序规则,否则编译器不知道如何进行排序,高级排序只是在排序规则上再进行一次逻辑规则指定,并不复杂。

set/multiset容器

set容器基本概念

简介:所有元素都会在插入时自动被排序
本质:set/multiset属于关联式容器,底层结构是用二叉树实现。
set和multiset区别:
 set不允许容器中有重复的元素
multiset允许容器中有重复的元素

set容器构造和赋值

set容器大小和交换

功能描述:统计set容器大小以及交换set容器
 函数原型:size();//返回容器中的元素的数目
* empty();//判断容器是否为空
* swap(st);//交换两个集合容器

 set插入和删除


* 功能描述:set容器进行插入数据和删除数据
* 函数原型:
* insert(elem);//在容器中插入元素。
* clear();//清除所有元素
* erase(pos); //删除POS迭代器所指的元素,返回下一个元素的迭代器。
* erase(beg,end);//删除区间【beg,end】的所有元素,返回下一个元素的迭代器。
* erase(elem)//删除容器中值为elem的元素;

set查找和统计


功能描述:对set容器进行查找以及统计数据
函数原型:
find(key);//查找key是否存在,若存在,返回该键的元素的迭代器;若不存在,返回set.end();
count(key);//统计key的元素个数,要么是0,要么是1 

 

set和multiset区别


* 区别:set不可以插入重复数据,而multiset可以
* set插入数据的同时会返回插入结果,表示插入是否成功
* multiset不会检测数据,因此可以插入重复数据

 总结:

如果不允许插入重复数据可以用set容器

允许插入重复数据用multiset容器。

pair使用 对组创建

功能描述:成对出现的数据,利用对组可以返回两个数据
* 两种创建方式:
* pair<type,type> p(value1,value2);
* pair<type,type> p=make_pair(value1,value2);

set容器内置类型排序


* 学习目标:set容器默认排序规则从小到大,掌握如何改变排序规则
* 主要技术点:利用仿函数,可以改变排序规则。

 set容器自定义数据类型排序

map/multimap容器 

map基本概念:


* 简介:map中所有元素都是pair
* pair中第一个元素为key(键值),起到索引作用,第二个为value(实值)
所有元素都会根据元素的键值自动排序
本质:map/multimap属于关联式容器,底层结构是用二叉树实现。
优点:可以根据key值快速找到value值
map和multimap区别:
map不允许容器中有重复key值元素
multimap允许容器有重复key值元素

map容器的创建和构造


* 总结:map中所有元素都是成对出现,插入数据时候要使用对组

 map容器大小和交换


* 功能描述:统计map容器大小以及交换map容器
* 函数原型:
size();//返回容器中元素的数目
empty();//判断容器是否为空
swap(mp);//交换两个集合容器

map容器插入和删除


* 功能描述:map容器进行插入数据和删除数据
* 函数原型:insert(elem);//在容器中插入数据
* clear();//清除所有元素
* erase(pos);删除POS迭代器所指的元素,返回下一个元素的迭代器。
* erase(beg,end);//删除区间[beg,end]的所有元素,返回下一个元素的迭代器。
* erase(key);//删除容器中值为key的元素 

map查找和统计


* 功能描述:对map容器进行查找数据以及统计数据
* 函数原型:
find(key);//查找key是否存在,返回该键的元素的迭代器;若不存在,返回map.end();
count();//统计key的元素个数。 

map容器内置数据类型排序


* map容器默认排序规则为按照key值进行从小到大排序,掌握如何改变排序规则
主要技术点:利用仿函数,可以改变排序规则 

 map容器自定义数据类型排序

 总结:利用仿函数可以指定map容器的排序规则
对于自定义数据类型,map必须指定排序规则,同set容器。

容器总结案例:

#include <iostream>
#include <vector>
#include <map>
using namespace std;
#define cehua 1
#define meisu 2
#define yangfa 3
/*案例描述:公司今天招聘了10个员工(ABCDEFGHIJ),10个员工进入公司后,需要指派员工在哪个部门工作
* 员工信息有:姓名 工资组成;部门分为:策划,美术,研发
* 随机给10名员工分配部门和工资
* 通过multimap进行信息的插入key(部门编号)value(员工)
* 分部门显示员工信息
* 实现步骤
* 1.创建10名员工,放到vector中
* 2.遍历vector容器,取出每个员工,进行随机分组
* 3.分组后,将员工部门编号作为key,具体员工作为value,放到multimap容器中
* 4.分部门显示员工信息*/
class person {
public:
	string m_name;
	int m_wage;
};
void createperson(vector<person>&p) {
	for (int i = 0;i<10;i++) {
		string name = "员工";
		string workname = "ABCDEFGHIJ";
		name += workname[i];
		person p1;
		p1.m_name = name;
		p1.m_wage = rand() % 10000+10000;
		p.push_back(p1);
	}
}
void groupperson(vector<person>& p, multimap<int, person>&mu) {
	
	for (vector<person>::iterator it = p.begin();it!=p.end();it++) {
		int key = 1+rand() % 3;
		person p1;
		p1.m_name =(*it).m_name;
		p1.m_wage =(*it).m_wage;
		mu.insert(make_pair(key,p1));	
	}
}
void showperson(multimap<int, person>&mu) {
	int index;
	multimap<int, person>::iterator pos;
	int count=mu.count(cehua);
	pos= mu.find(cehua);
	cout << " 部门:" << "策划" << endl;
	index = 0;
	for (;index<count&&pos!=mu.end();pos++,index++) {
		 cout << "姓名:" <<(*pos).second.m_name << " 工资:" << (*pos).second.m_wage << endl;
	}
	count = mu.count(meisu);
	pos = mu.find(meisu);
	index = 0;
	cout << " 部门:" << "美术" << endl;
	for (; index < count && pos != mu.end(); pos++, index++) {
		cout << "姓名:" << (*pos).second.m_name << " 工资:" << (*pos).second.m_wage << endl;
	}
		count = mu.count(yangfa);
		pos = mu.find(yangfa);
		cout << " 部门:" << "研发" << endl;
	index = 0;
	for (; index < count&& pos != mu.end(); pos++, index++) {
			cout << "姓名:" << (*pos).second.m_name << " 工资:" << (*pos).second.m_wage << endl;
		}
	/*int key = 1;
		cout << " 部门:" << "策划" << endl;
		for (multimap<int, person>::iterator it = mu.begin(); it != mu.end(); it++) {
			if (key == (*it).first) cout << "姓名:" << (*it).second.m_name << " 工资:" << (*it).second.m_wage<<endl;
		}
		key++;
		cout << " 部门:" << "美术" << endl;
		for (multimap<int, person>::iterator it = mu.begin(); it != mu.end(); it++) {
			if (key == (*it).first) cout << "姓名:" << (*it).second.m_name << " 工资:" << (*it).second.m_wage << endl;
		}
		key++;
		cout << " 部门:" << "研发" << endl;
		for (multimap<int, person>::iterator it = mu.begin(); it != mu.end(); it++) {
			if (key == (*it).first) cout << "姓名:" << (*it).second.m_name << " 工资:" << (*it).second.m_wage << endl;
		}*/
}
void test01() {
	vector<person> v1;
	multimap<int, person>mu;
	//员工创建
	createperson(v1);
	for (vector<person>::iterator it = v1.begin(); it != v1.end(); it++) {
		cout<<"姓名:" <<( * it).m_name << "工资:"<< (*it).m_wage << endl;
	}
	//员工分组
	groupperson(v1,mu);
	//员工显示
	showperson(mu);

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

容器到此在这结束!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值