第六章——STL介绍

6.1 vector的常见用法详解
vector是一个“长度根据需要而自动改变的数组”
如果碰到普通数组超内存的情况,使用vector方法让我们方便很多。
可以以连接表的方式存储图
头文件:#include
(1)vector 的定义
单独定义一个vector
vector name;
typename也可以是一个容器
vector<vector > name
可以当作二维数组理解
(2)vector容器内元素的访问
两种,一是下标访问,二是通过迭代器访问
1.通过下标访问,如vector vi,直接访问vi[i],i等于i-sizeof(vi).
2.通过迭代器访问,迭代器类似于指针,其定义为

vector<typename>::iterator it;

可以通过*it来访问容器内的元素
美国人思维比较喜欢左闭右开,end()是指尾元素的下一个地址。

#include<cstdio>
#include<vector>
using namespace std;
int main (){
	vector<int > vi;
	for(int i=1;i<=5;i++)
	vi.push_back(i);
	for(vector<vi>::iterator it=vi.begin();it!=vi.end();it++){
		printf("%d",*it);
	}
	return 0;
}

STL只有vector与string有vi.begin()加整数的写法
(3)vector常用函数
1.push_back()
push_back(x),在vector后面加元素,时间复杂度O(1)
2.pop_back()
有添加就会有删除,删除vector尾元素
3.size()
获取vector中元素的个数
4.clear()
清空vector所有的元素
5.insert()
insert(it,x),用来在vector的任意迭代器it处添加一个元素x,

#include<cstdio>
#include<vector>
using namespace std;
int main (){
	vector<int > vi;
	for(int i=1;i<=5;i++)
	vi.push_back(i);
	vi.insert(vi.begin()+2,6);
	for(int i=0;i<vi.size();i++)
	printf("%d ",vi[i]); 
	return 0;
}

6.erase()
两种用法:删除单个元素,删除一个区间所有元素

删除单个元素:erase(it) 删除迭代器it处的元素

#include<cstdio>
#include<vector>
using namespace std;
int main (){
	vector<int > vi;
	for(int i=5;i<=9;i++)
	vi.push_back(i);
	vi.erase(vi.begin()+3);
	for(int i=0;i<vi.size();i++)
	printf("%d ",vi[i]); 
	return 0;
}

删除区间所有元素:erase(first,last),即删除[first,last)内所有元素

#include<cstdio>
#include<vector>
using namespace std;
int main (){
	vector<int > vi;
	for(int i=5;i<=9;i++)
	vi.push_back(i);
	vi.erase(vi.begin()+1,vi.begin()+4);
	for(int i=0;i<vi.size();i++)
	printf("%d ",vi[i]); 
	return 0;
}

(4)vector常用用途
1.储存数组
2.用邻接表存储图
6.2 set的常见用法
set翻译为集合,是一个内部自动有序且不含重复元素。
需添加#include
1.set定义
set name;
set name //node结构体
set数组与vector相同
set s[arraysize]
这样s[0]到s[arraysize-1]中每一个都是一个容器set
2.set内元素的访问
set只能通过迭代器访问
set ::iterator it;
由于除了vector与string支持*(it+i)的访问方式,所以只能枚举

#include<cstdio>
#include<set>
using namespace std;
int main (){
	set<int > st;
	st.insert(3);
	st.insert(5);
	st.insert(3);
	st.insert(2);
	for(set<int >::iterator it=st.begin();it!=st.end();it++){ //不支持it<st.end()的写法 
		printf("%d ",*it); 
	}
	return 0;
}

3 . set常用函数
(1)insert()
insert(x) 可将x插入set容器中。
(2)find()
find(value) 返回set中对应值value的迭代器。
返回值为指向键等于key的元素的迭代器,否则返回end()

#include<cstdio>
#include<set>
using namespace std;
int main (){
	set<int > st;
	st.insert(5);
	st.insert(4);
	set<int >::iterator it=st.find(1);
		printf("%d\n",*it); 
	return 0;
}

(3)erase()
删除单个元素和区域所有元素
删除单个元素可通过find(),也可直接删除
区间所有元素删除:

#include<cstdio>
#include<set>
using namespace std;
int main (){
	set<int > st;
	st.insert(5);
	st.insert(4);
	st.insert(10);
	set<int >::iterator it=st.find(5);
	st.erase(it,st.end());
	for(it=st.begin();it!=st.end();it++)
	printf("%d ",*it);
	return 0;
}

(4)size()
用来获取set的元素
(5)clear()
3.set常见用途
主要用途:去重自动排序
set中元素是唯一的。若需要不去重用multiset。unordered_set

6.3 string的常见用法
头文件#include
1.string 的定义
string str;
string str=“abcd”;
2.string中内容的访问

#include<cstdio>
#include<string>
using namespace std;
int main (){
	string str="abecd";
	printf("%c",str[2]);
	return 0;
}

如果要读入和输出只能用cin和cout,若要用printf,需要转换
(2)通过迭代器访问,并可以用*it来访问string的每一位

#include<cstdio>
#include<string>
using namespace std;
int main (){
	string str="abecd";
	for(string::iterator it=str.begin();it!=str.end();it++)
	printf("%c",*it);
	return 0;
}

string与vector一样支持直接对迭代器进行加减
3.string常见函数
(1)operator+=,string相加等于string相接
(2)compare operator
两个string可直接使用==、!=、<、>等,比较规则是字典序
(3)length()与size(),返回string的长度
(4)insert(),有很多用法
insert(pos,string) //pos为位置
insert(it,it2,it3) //it是需要插入的位置,it2、it3是首尾迭代器

#include<cstdio>
#include<iostream>
#include<string>
using namespace std;
int main (){
	string str1="momo",str2="dada";
	str1.insert(str1.begin()+2,str2.begin()+1,str2.end());
	cout<<str1<<endl;
	return 0;
}

(5)erase()
删除单个元素、区间元素
前两种与其他容器相同
str.earse(pos,length) //pos是位置,length是删除的个数

#include<cstdio>
#include<iostream>
#include<string>
using namespace std;
int main (){
	string str1="momodada";
	str1.erase(3,2);
	cout<<str1<<endl;
	return 0;
}

(6)clear()
(7)substr()
substr(pos,len) 返回从pos号开始,长度为len
(8)string::npos
string::npos是一个常数-1或者4294967295
用以作用find函数失配时的返回值
(9)find()
str.find(str2),str2是str的字串时,返回其在str第一次出现的位置,否则返回string::npos
(10)replace()
str.replace(pos,len,str2).把str从pos位置开始,长度为len的子串替换成str2.
str.replace(it1,it2,str2).把str的迭代器[it1,it2)范围的子串替换str2.
PAT 1060

#include<iostream>
#include<string>
using namespace std;
int n; //有效位数
string deal(string s,int &e){
	int k=0; //s的下标 
	while(s.length()>0&&s[0]=="0")
	s.erase(s.begin());  //去掉前导数
	if(s[0]=="."){  //去掉前导0,是.说明是小数 
		s.erase(s.begin());
		while(s.length()>0&&s[0]=="0")
		s.erase(s.begin());
		e--; 
	}
	else
	{
		while(k<s.length()&&s[k]!="."){ //如果不碰到".",e++ 
			k++;
			e++; 
		}
		if(k<s.length()){//碰到小数点
		s.erase(s.begin()+k); 
		}
		if(s.length==0)  //前导数去掉,长度为0,说明这个数为0 
		e=0;
		int num=0;
		k=0;
		string res;
		while(num<n){  //只要精度还没有到n 
			if(k<s.length())
			res+=s[k++];
			else
			res+='0';
			num++;
		} 
	}
	 return res;
} 
int main (){
	string s1,s2,s3,s4;
	cin>>n>>s1>>s2;
	int e1=0,e2=0;//s1与s2的指数
	s3=deal(s1,e1);
	s4=deal(s2,e2);
	if(s1==s2&&e1==e2){
		cout<<"YES 0."<<s3<<"*10^"<<e1<<endl;
	} 
	else
	cout<<"NO.0"<<s3<<"*10^"<<e1<<"0."<<s4<<"*10^"<<e2<<endl;
	return 0;
}

6.4 map的常用用法

map翻译成映射,可以将任何基本类型(包括STL容器)映射到基本类型(包括STL容器)
头文件:#include
1.map的定义
map<typename1,typename2> mp; 需要确定(映射前)key的类型和(映射后)value
字符串的映射,必须使用string而不使用char
2.map元素的访问
(1)下标

#include<cstdio>
#include<map>
using namespace std;
int main (){
	map<char,int >mp;
	mp['c']=20;
	mp['c']=30;
	printf("%d\n",mp['c']);
	return 0;
}

(2)通过迭代器访问
与其他STL容器相同
map<typename1,typename2> ::iterator it;
必须通过一个it来访问key和value.
实际上,map可通过it->first来访问key,it->second来访问value

#include<cstdio>
#include<map>
using namespace std;
int main (){
	map<char,int >mp;
	mp['c']=20;
	mp['m']=30;
	mp['a']=40;
	for(map<char,int>::iterator it=mp.begin();it!=mp.end();it++){
		printf("%c %d\n",it->first,it->second);
	}
	return 0;
}

map会以键值而从小到大自动排序,这是由于map内部是由红黑树实现的(set也是)。
3.map常数解析
(1)find()
find(key)返回键是key的迭代器
(2)erase()
删除单个元素两种方法:mp.erase(it)和mp.erase(key)
删除一个区域的所有元素:mp.erase(first,second)
(3)size()
来获取map中映射的对数
(4)clear()
4.map常见用途
(1)需要建立字符串与整数之间映射的题目
(2)判断大整数或者其他类型是否存在
(3)字符串与字符串的题也可能遇到
map的键与值是唯一的,而需要一个键对应多个值,就只能用multimap。另外,C++还支持unordered_map使其只映射而不按照key排序
6.5 queue的常见用法
queue翻译为队列,实现了一个先进先出的容器
1.queue的定义:
头文件#include
queue name
2.容器内的访问
由于queue是一个先进先出的容器,所以他只能访问头元素front()和尾元素back()
3.queue的常用函数
(1)push()
push(x)将x入队
(2)front()、back()
分别获得队首元素、队尾元素
(3)pop()
pop()让首元素出队
(4)empty()
检查是否为空,空则返回true,非空则返回false
(5)size()
元素的个数
4.常见用途
(1)需要实现广度优先搜索,可以用queue代替。
(2)在用front()、pop()时,先要用empty()判断是否为空,否则可能因为队空而出现错误
(3)deque和优先队列(priority_queue),前者是首尾皆可插入、删除,后者使用堆排列将最大元素置于队首
6.6 priority_queue的常见解法
队首元素一定是优先级最高的那个
1.定义:
#include
2.元素的访问:
没有front()与back(),只有top()
3.常用函数
(1)push()
(2) top() 获得队首元素
(3)pop() ,令队首元素出队
(4)empty() 检查是否为空
(5)size()
4.优先级的设置
less 表示数字大的优先级大
greater表示数字小的优先级大
priority_queue<int ,vector ,less > q;
(2)结构体的优先级设置:
重载:重载是指对已有的运算符进行重新定义,也就是说,改变小于号的功能

struct fruit{
	string name;
	int price;
	friend bool operator<(fruit f1,fruit f2){
		return f1.price>f2.price;
	}
};

优先队列的这个函数与sort函数cmp函数的效果是恰恰相反的
比较类中的参数,需要加上const、&。
5.priority_queue的用途
(1)解决一些贪心问题,Dijkstra算法进行优化
(2)top前,要先判断是否为空(empty)
6.7 stack的常见用法详解
stack翻译成栈,后进先出的容器。
1.定义:
#include
stackname
2.容器内的访问元素
只能通过top()访问栈顶元素
3.stack常用函数
(1)push.()
(2) top.()
(3) pop.()
(4)empty.()
(5)size()
5.常见用途:
模拟一些递归
6.8 pair的常见用法
想要把两个元素绑在一起,却又不想用struct
头文件:#include
pair有两个参数,一个是first,second ,它们可以是任意容器或者类型
2.访问:
按照结构体的方式进行访问即可
3.pair常用函数
比较操作符,pair可以直接使用==、!=、<=、>=
比较规则是以first的大小为标准,first一样就比较second.
4.pair的常见用途
(1)用来代替二元结构体及其构造函数
(2)作为map的键值对来进行插入
6.9 algorithm头文件下的常用函数
6.9.1 max(),min()、abs()
返回两者较大的、返回两者较小的、返回绝对值
返回x、y、z中最大的
max(z,max(x,y))
abs()必须是整数、浮点数请用
6.9.2 swap()
交换值
6.9.3 reverse()
reverse(it1,it2),可以将指针数组在[it1,it2)之间的元素或者迭代器中的元素进行翻转

#include<cstdio>
#include<algorithm>
using namespace std;
int main (){
	int a[10];
	for(int i=0;i<6;i++)
	a[i]=i;
	reverse(a,a+6);
	for(int i=0;i<6;i++)
	printf("%d ",a[i]);
	return 0;
}

也可以对字符串进行转换
6.9.4 next_permutation()
给出一个序列在全排列中的下一个序列

#include<cstdio>
#include<algorithm>
using namespace std;
int main (){
	int a[10]={1,5,6};
	do{
		printf("%d %d %d\n",a[0],a[1],a[2]);
	}while(next_permutation(a,a+3));
	return 0;
}

6.9.5 fill()
fill()可以把数组或容器中的某一段区间赋为某一相同的值。和memset不同的是,可以是任意值。
6.9.6 sort()
sort(首元素地址,尾元素地址的下一位,比较函数)
6.9.7 lower_bound()、upper_bound()
lower_bound()和upper_bound()需要在一个有序的容器里;
lower_bound(first,last,val),寻找数组或容器中[first,last)范围内第一个大于等于val的位置,如果是数组返回该位置的指针,如果是容器,返回迭代器。
upper_bound()第一个大于val的位置
如果求下标,即减去首地址即可

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值