C++基础学习笔记09——STL

STL

C++面向对象和泛型编程的思想,目的就是复用性的提升
STL(Standard Template Library,标准模板库)
STL从广义上分为:容器(container)算法(algorithm)迭代器(iterator)
容器和算法之间通过迭代器进行无缝连接
STL六大组件:
容器:各种数据结构
算法:各种常见的算法
迭代器:扮演了容器和算法之间的胶合剂
仿函数:行为类似函数,可作为算法的某种策略
适配器:一种用来修饰容器或者仿函数或者迭代器接口的东西
空间适配器:负责空间的配置与管理

1. STL初识

容器:vector
算法:for_each
迭代器:vector::iterator

	vector<int> v;
	for(int i=0;i<10;i++){
		v.push_back(i);	//插入数据 
	}
	for(vector<int>::iterator it=v.begin();it!=v.end();it++){	//遍历容器 
		cout<<*it<<endl;
	}

vector嵌套:

	vector< vector<int> > v;
	vector<int> v1;
	vector<int> v2;
	vector<int> v3;
	for(int i=0;i<4;i++){
		v1.push_back(i);
		v2.push_back(i+1);
		v3.push_back(i+2);
	}
	v.push_back(v1);
	v.push_back(v2);
	v.push_back(v3);
	for(vector< vector<int> >::iterator it=v.begin();it!=v.end();it++){
		for(vector<int>::iterator vit=(*it).begin;vit!=(*it).end;vit++){
			cout<<*vit<<endl;
		}
	}

相当于二维数组

2. string容器

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

	string s1;	//创建空字符串 
	const char* s2="hello world";
	string s3(s2);	//调用拷贝构造函数 
	string s4(10,'a');	//10个字符a赋值给s4 

2.2 赋值

	string s1="hello world";	//字符s1赋值 
	string s2=s1;	//字符s1赋值给s2 
	string s3='a';	//字符值赋给当前字符串 
	string s4;
	s4.assign("hello world");	//字符串s赋值给当前字符 
	string s5;
	s5.assign("hello world",5);	//把字符串前5个字符赋值给当前字符串 
	string s6;		
	s6.assign(s5);		//把字符串s赋值给当前字符串 
	string s7;
	s7.assign(5,'x');	//用n个字符c赋值给当前字符串 

2.3 拼接

	string s1="我";
	s1+="爱玩";
	string s2="游戏";
	s1+=s2;
	string s3="I";
	s3.append(" love ");	//把字符串s接到当前字符串结尾 
	s3.append("game ab",4);	//把字符串s前n个字符连接到当前字符串结尾 
	s3.append(s2);		//将字符串s连接到当前字符串结尾 
	s3.append(s2,4,3);	//将字符串s中从pos开始的n个字符连接到当前字符串结尾,s.append(字符串,起始位置,字符数)

2.4 查找与替换

	string s1="abcdefgde";
	int pos=s1.find("de");	//查找起始位置
	s1.replace(1,3,"aaaaa");
	//s.replace(起始位置,替换数目,替换字符串)

总结:
find查找是从左往右,rfind从右往左
find找到字符串后返回查找的第一个字符位置,找不到返回-1
replace在替换时,要指定从哪个位置起,多少个字符,替换成什么

2.5 插入和删除

	string s1="hello";
	s1.insert(1,"he");	//在指定位置插入字符串 
	s1.insert(4,5,'c');	//在指定位置插入指定数目字符 
	s1.erase(5);	//从指定位置开始删除字符串
	s1.erase(3,2);	//从指定位置删除指定数目字符 

总结:
插入:
s.insert(指定位置,字符串(字符));
s.insert(指定位置,指定数目,指定字符);
删除:
s.erase(指定位置,指定数目(可省略));

2.6 子串获取

	string s1="abcdef";
	string s2=s1.substr(2,3);	//从字符串s指定位置开始截取指定数目字符 

3. vector容器

3.1 基本概念
功能:与数组相似,单端数组
与数组区别:vector可以动态扩展

3.2 构造

	vector<int> v1;
	for(int i=0;i<10;i++){
		v1.push_back(i); 
	}
	vector<int> v2(v1.begin(),v1.end());	//将区间begin()到end()的值赋给v2
	vector<int> v3(10,100);	//将指定数目的值赋值给v3
	vector<int> v4(v3);	//拷贝构造 

3.3 赋值

	vector<int> v2;
	v2=v1;
	vector<int> v3;
	v3.assign(v1.begin(),v1.end());	//将begin()到end()的值赋值给v3 
	vector<int> v4;
	v4.assign(10,100); 

3.4 容量和大小

	v1.empty();	//判断容器是否为空
	v1.capacity() ;	//容器的容量
	v1.size();	//返回容器中元素个数
	v1.resize(6);	//重新指定容器的长度,若容器变长,则用默认值填充新位置
					//若容器变短,则末尾超出容器长度的元素被删除
	v1.resize(6,8); //重新指定容器的长度,若容器变长,则用指定值填充新位置
					//若容器变短,则末尾超出容器长度的元素被删除

3.5 插入和删除

	v1.push_back(ele); //在尾部插入元素ele
	v1.pop_back();	//删除最后一个元素
	v1.insert(const_iterator pos,ele);	//迭代器指向位置pos插入元素ele
	v1.insert(const_iterator pos,int count,ele);	//迭代器指向位置pos插入count个元素ele
	v1.erase(const_iterator pos);	//删除迭代器指向的元素
	v1.erase(const_iterator start,const_iterator end);	//删除迭代器从start到end之间的所有元素
	v1.clear();	//删除容器中所有元素 

3.6 数据存取

	v1.at(int idx);	//返回索引idx所指的数据
	cout<<v1[idx];	//返回索引idx所指的数据
	v1.front();		//返回容器中第一个数据元素
	v1.back();		//返回容器中最后一个数据元素 

4. deque容器

功能:双端数组,可以对头端进行插入删除操作
deque与vector区别:
vector对于头部的插入删除操作效率低,数据量越大,效率越低
deque相对而言,对头部的插入删除速度比vector快
vector访问元素的速度会比deque快

4.1 构造

	deque<int> d1;
	for(int i=0;i<10;i++){
		d1.push_back(i); 
	}
	deque<int> d2(d1.begin(),d1.end());	//将区间begin()到end()的值赋给d2
	deque<int> d3(10,100);	//将指定数目的值赋值给d3
	deque<int> d4(v3);	//拷贝构造 

4.2 赋值

	deque<int> d2;
	d2=d1;
	deque<int> d3;
	d3.assign(d1.begin(),d1.end());	//将begin()到end()的值赋值给d3 
	deque<int> d4;
	d4.assign(10,100); 

4.3 deque容量和大小

	d1.empty();	//判断容器是否为空
	d1.capacity() ;	//容器的容量
	d1.size();	//返回容器中元素个数
	d1.resize(6);	//重新指定容器的长度,若容器变长,则用默认值填充新位置
					//若容器变短,则末尾超出容器长度的元素被删除
	d1.resize(6,8); //重新指定容器的长度,若容器变长,则用指定值填充新位置
					//若容器变短,则末尾超出容器长度的元素被删除

4.4 插入和删除

	deque<int> d;
	d.push_back(elem);		//在容器尾部添加一个数据 
	d.push_front(elem);		//在容器头部插入一个数据 
	d.pop_back();			//删除容器最后一个数据 
	d.pop_front();			//删除容器第一个数据 
	d.insert(pos,elem);		//在pos位置插入一个elem元素的拷贝,返回新数据的位置 
	d.insert(pos,n,elem);	//在pos位置插入n个elem数据,无返回值 
	d.insert(pos,beg,end);	//在pos位置插入[beg,end)区间的数据,无返回值 
	d.clear();				//清空所有数据 
	d.erase(beg,end);		//删除[beg,end)区间的数据,返回下一个数据的位置 
	d.erase(pos);			//删除pos位置的数据,返回下一个数据的位置 

4.5 数据存取

	d1.at(int idx);	//返回索引idx所指的数据
	cout<<d1[idx];	//返回索引idx所指的数据
	d1.front();		//返回容器中第一个数据元素
	d1.back();		//返回容器中最后一个数据元素

5. stack容器

概念:stack是一种先进后厨的数据结构

	stack<int> s;	//构造栈
	s.push(elem);	//向栈顶添加元素
	s.pop();		//从栈顶移除第一个元素 
	s.top();		//返回栈顶元素 
	s.empty();		//判断栈是否为空 
	s.size(); 		//返回栈的大小 

6. queue容器

概念:queue是一种先进先出的数据结构

	queue<int> q;	//构造队列 
	q.push(elem);	//向队尾添加元素	
	q.pop();		//从对头移除第一个元素 
	q.back();		//返回最后一个元素 
	q.front();		//返回第一个元素 
	q.empty();		//判断队列是否为空 
	q.size();		//返回队列大小 

7. list容器

功能:将数据进行链式存储
STL中的链表是一个双向循环链表
由于链表的存储方式并不是连续的内存空间,因此链表list中的迭代器只支持前移和后移,属于双向迭代器
list的有点:
采用动态存储分配,不会造成内存浪费和溢出
链表执行插入和删除操作十分方便,修改指针即可,不需要大量移动元素
list的缺点:
链表灵活,但是空间和时间额外耗费较大

7.1 构造

	list<int> l1;
	for(int i=0;i<10;i++){
		l1.push_back(i); 
	}
	list<int> l2(l1.begin(),l1.end());	//将区间begin()到end()的值赋给l2
	list<int> l3(10,100);	//将指定数目的值赋值给l3
	list<int> l4(l3);	//拷贝构造 

7.2 赋值

	list<int> l2;
	l2=l1;
	list<int> l3;
	l3.assign(l1.begin(),l1.end());	//将begin()到end()的值赋值给l3 
	list<int> l4;
	l4.assign(10,100); 

7.3 大小

	l1.empty();	//判断容器是否为空
	l1.size();	//返回容器中元素个数
	l1.resize(6);	//重新指定容器的长度,若容器变长,则用默认值填充新位置
					//若容器变短,则末尾超出容器长度的元素被删除
	l1.resize(6,8); //重新指定容器的长度,若容器变长,则用指定值填充新位置
					//若容器变短,则末尾超出容器长度的元素被删除

7.3 插入和删除

	list<int> l;
	l.push_back(elem);		//在容器尾部添加一个数据 
	l.push_front(elem);		//在容器头部插入一个数据 
	l.pop_back();			//删除容器最后一个数据 
	l.pop_front();			//删除容器第一个数据 
	l.insert(pos,elem);		//在pos位置插入一个elem元素的拷贝,返回新数据的位置 
	l.insert(pos,n,elem);	//在pos位置插入n个elem数据,无返回值 
	l.insert(pos,beg,end);	//在pos位置插入[beg,end)区间的数据,无返回值 
	l.clear();				//清空所有数据 
	l.erase(beg,end);		//删除[beg,end)区间的数据,返回下一个数据的位置 
	l.erase(pos);			//删除pos位置的数据,返回下一个数据的位置 
	l.remove(elem);			//删除容器中所有与elem值匹配的元素

7.4 数据存取

	l.front();	//返回第一个元素
	l.back();	//返回最后一个元素

7.5 反转与排序

	l.reverse();	//反转链表
	l.sort();		//链表排序

8. set/multiset 容器

set基本概念:所有元素都会在插入时自动排序
set与multiset区别:
set不允许容器中有重复的元素
multiset允许容器中有重复的元素

8.1 构造和赋值

	set<int> s;
	s.insert(elem);		//插入数据elem

8.2 大小和交换

	s.empty();	//判断容器是否为空
	s.size();	//返回容器中元素个数
	s.swap(s1);	//交换两个容器的元素

8.3 插入和删除

	s.insert(elem);			//在容器中插入元素
	s.clear();				//清空所有数据 
	s.erase(beg,end);		//删除[beg,end)区间的数据,返回下一个数据的位置 
	s.erase(pos);			//删除pos迭代器所指位置的数据,返回下一个数据的位置 
	s.erase(elem);			//删除容器中elem值的元素

8.4 查找和统计

	s.find(key);		//查找key元素是否存在,返回该元素的迭代器
	s.count(key);		//统计key元素的个数

9. pair容器

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

	pair<string,int> p1("Tom",18);
	pair<string,int> p2=make_pair("Jerry",18);
	cout<<p1.first<<" "<<p1.second<<endl;
	cout<<p2.first<<" "<<p2.second<<endl;	//访问两个数据

10. map容器

简介:
map容器中所有元素都是pair
pair中第一个元素为key(键值),第二个元素为value(实值)
所有元素都会根据元素的键值自动排序
优点:
可以根据key值快速找到value
map和multimap区别:
map不允许容器中有重复的key值元素
multimap中允许荣有重复的key值元素

10.1 构造

	map<int,int> m;
	m.insert(pair<int,int>(1,10));
	m.insert(pair<int,int>(2,20));
	m.insert(pair<int,int>(3,30));
	m.insert(pair<int,int>(4,40));
	for(map<int,int>::iterator it=m.begin();it!=m.end();it++){
		cout<<(*it).first<<" "<<(*it).second<<endl;		//访问map容器中的元素
	}

10.2 大小和交换

	m.empty();	//判断容器是否为空
	m.size();	//返回容器中元素个数
	m.swap(s1);	//交换两个容器的元素

10.3 插入和删除

	m.insert(elem);		//在容器中插入元素
	m.clear();			//清除所有元素 
	m.erase(pos);		//删除pos迭代器所指的元素,返回下一个元素的迭代器 
	m.erase(beg,end);	//删除区间[beg,end)的所有元素,返回下一个元素的迭代器 
	m.erase(key); 		//删除容器中值为key的元素 

四种插入方式:

	m.insert(pair<int,int>(1,10));
	m.insert(make_pair(2,20));
	m.insert(map<int,int>::value_type(3,30));
	m[4]=40;

10.4 查找和统计

	m.find(key);		//查找key元素是否存在,返回该元素的迭代器
	m.count(key);		//统计key元素的个数
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值