STL使用汇总
vector
vector常用函数
#include<vector>
vector<int> a,b;
//b为向量,将b的0-2个元素赋值给向量a
a.assign(b.begin(),b.begin()+3);
//a含有4个值为2的元素
a.assign(4,2);
//返回a的最后一个元素
a.back();
//返回a的第一个元素
a.front();
//返回a的第i元素,当且仅当a存在
a[i];
//清空a中的元素
a.clear();
//判断a是否为空,空则返回true,非空则返回false
a.empty();
//删除a向量的最后一个元素
a.pop_back();
//删除a中第一个(从第0个算起)到第二个元素,也就是说删除的元素从a.begin()+1算起(包括它)一直到a.begin()+3(不包括它)结束
a.erase(a.begin()+1,a.begin()+3);
//在a的最后一个向量后插入一个元素,其值为5
a.push_back(5);
//在a的第一个元素(从第0个算起)位置插入数值5,
a.insert(a.begin()+1,5);
//在a的第一个元素(从第0个算起)位置插入3个数,其值都为5
a.insert(a.begin()+1,3,5);
//b为数组,在a的第一个元素(从第0个元素算起)的位置插入b的第三个元素到第5个元素(不包括b+6)
a.insert(a.begin()+1,b+3,b+6);
//返回a中元素的个数
a.size();
//返回a在内存中总共可以容纳的元素个数
a.capacity();
//将a的现有元素个数调整至10个,多则删,少则补,其值随机
a.resize(10);
//将a的现有元素个数调整至10个,多则删,少则补,其值为2
a.resize(10,2);
//将a的容量扩充至100,
a.reserve(100);
//b为向量,将a中的元素和b中的元素整体交换
a.swap(b);
//b为向量,向量的比较操作还有 != >= > <= <
a==b;
vector 创建二维数组
创建
vector<vector<int>>ans;
//不过这个时候ans 大小是0,不能访问。
初始化
// 创建有n行
vector<vector<int>>ans(N);
//n*m,并初始化为0
vector<vector<int>>ans(N,vector<int>(m,0));
例子
int main()
{
while(cin>>n>>q){
vector<vector<int>>ans(N);
while(q--){
cin>>fg;
if(fg == 0){
cin>>t>>x;
ans[t].push_back(x);
}else if(fg == 1){
cin>>t;
show(ans[t]);
}else{
cin>>t;
ans[t].clear();
}
}
}
return 0;
}
list
list常用函数
Lst1.assign() 给list赋值
Lst1.back() 返回最后一个元素
Lst1.begin() 返回指向第一个元素的迭代器
Lst1.clear() 删除所有元素
Lst1.empty() 如果list是空的则返回true
Lst1.end() 返回末尾的迭代器
Lst1.erase() 删除一个元素
Lst1.front() 返回第一个元素
Lst1.get_allocator() 返回list的配置器
Lst1.insert() 插入一个元素到list中
Lst1.max_size() 返回list能容纳的最大元素数量
Lst1.merge() 合并两个list
Lst1.pop_back() 删除最后一个元素
Lst1.pop_front() 删除第一个元素
Lst1.push_back() 在list的末尾添加一个元素
Lst1.push_front() 在list的头部添加一个元素
Lst1.rbegin() 返回指向第一个元素的逆向迭代器
Lst1.remove() 从list删除元素
Lst1.remove_if() 按指定条件删除元素
Lst1.rend() 指向list末尾的逆向迭代器
Lst1.resize() 改变list的大小
Lst1.reverse() 把list的元素倒转
Lst1.size() 返回list中的元素个数
Lst1.sort() 给list排序
Lst1.splice() 合并两个list
Lst1.swap() 交换两个list
Lst1.unique() 删除list中重复的元素
遍历list
第一种
for(auto it = L.begin();it!=L.end();it++)
cout<<*it<<endl;
第二种
for (auto e:L) {
cout << e << endl;//auto循环更方便
}
erase
erase
是删除之后会返回下一个位置。
如
cur = L.erase(cur);
//会讲 cur位置的元素删除掉,然后返回下一个位置的迭代器
insert
insert
插入的是在当前位置的前一个位置,同时插入后返回插入位置的迭代器。
如
cur = L.insert(cur,x);
splice
作用是将另一个list中的元素复制
ans[t].splice(ans[t].end(),ans[s]);
queue
常用函数
1.入队:如q.push(x):将x元素接到队列的末端;
2.出队:如q.pop() 弹出队列的第一个元素,并不会返回元素的值;
3,访问队首元素:如q.front()
4,访问队尾元素,如q.back();
5,访问队中的元素个数,如q.size();
priority_queue
priority_queue常用函数
top 访问队头元素
empty 队列是否为空
size 返回队列内元素个数
push 插入元素到队尾 (并排序)
emplace 原地构造一个元素并插入队列
pop 弹出队头元素
swap 交换内容
大根堆,小根堆
默认是大顶堆
一般是:
//升序队列
priority_queue <int,vector<int>,greater<int> > q;//大根堆
//降序队列
priority_queue <int,vector<int>,less<int> >q; //小根堆
// 也可以通过重载运算符来得到想要的根堆。
set
set常用函数
有一个multiset
是它的兄弟,区别是里边的元素可以是重复的,在函数使用上基本上是一样的,如erase
,set删除的是单个,multiset 删除的是所有相同的。
begin(); // 返回指向第一个元素的迭代器
end(); // 返回指向迭代器的最末尾处(即最后一个元素的下一个位置)
clear(); // 清除所有元素
count(); // 返回某个值元素的个数
empty(); // 如果集合为空,返回true
equal_range(); //返回集合中与给定值相等的上下限的两个迭代器
erase()–删除集合中的元素
find()–返回一个指向被查找到元素的迭代器
get_allocator()–返回集合的分配器
insert()–在集合中插入元素
lower_bound()–返回指向大于(或等于)某值的第一个元素的迭代器
key_comp()–返回一个用于元素间值比较的函数
max_size()–返回集合能容纳的元素的最大限值
rbegin()–返回指向集合中最后一个元素的反向迭代器
rend()–返回指向集合中第一个元素的反向迭代器
size()–集合中元素的数目
swap()–交换两个集合变量
upper_bound()–返回大于某个值元素的迭代器
value_comp()–返回一个用于比较元素间的值的函数
find()
find()
返回的是一个迭代器位置,如果没有找到则是end()
auto it = ans.find(n);
if(it!=ans.end())
cout<<1<<endl;
else
cout<<0<<endl;
erase()
erase() 先通过 find()函数找到x元素的迭代器位置。如果不是end()就删除
注意:set中的erase()无返回值。
if(it!=ans.end())
ans.erase(it);
set取并集,交集,差集
基本介绍
set里面有set_intersection
(取集合交集)、set_union
(取集合并集)、set_difference
(取集合差集)、set_symmetric_difference
(取集合对称差集)等函数。
set_union
set_union(A.begin(),A.end(),B.begin(),B.end(),inserter(result,result.begin()));
for(int i=0;i<result.size();i++)
{
cout<<result[i]<<" ";
}
set_intersection
set_intersection(A.begin(),A.end(),B.begin(),B.end(),inserter(result,result.begin()));
for(int i=0;i<result.size();i++)
{
cout<<result[i]<<" ";
}
set_difference
set_difference(A.begin(),A.end(),B.begin(),B.end(),inserter(result,result.begin()));
for(int i=0;i<result.size();i++)
{
cout<<result[i]<<" ";
}
注意事项
与 map/multimap 不同的是,map/multimap中存储的是真正的键值对<key,value>,set 中只放 value,但与底层实际存放的是由<value,value>构成的键值对;
set中插入元素时,只需要插入 value 即可,不需要构造键值对;
set中的元素不可以重复;
使用set 的迭代器遍历 set中的元素,可以得到有序序列;
set中的元素默认按照小于来比较
set中查找某个元素,时间复杂度为:log2N;
代码:
int main()
{
while(~scanf("%d",&q)){
multiset<int>ans;
while(q--){
scanf("%d%d",&fg,&n);
if(fg == 0){
ans.insert(n);
int len = ans.size();
printf("%d\n",len);
}else if(fg == 1){
int state = ans.count(n);
printf("%d\n",state);
}else if(fg == 2)
ans.erase(n);
else{
int r;
cin>>r;
auto left = ans.lower_bound(n);
while(left!=ans.end()&&*left<=r)
{
printf("%d\n",*left);
left++;
}
}
}
}
return 0;
}
bitset
1、构造函数:
#include<bitset>
std::bitset<4> foo; //创建一个4位的位集,每一位默认为0
当整数的大小小于位数时,高位填充为0
std::bitset<4> foo(5); //用整数初始化 5二进制位:101 foo值:0101
当整数的大小超过位数时,从整数二进制的低位开始赋值,高位被舍弃
std::bitset<4> foo(19); //用整数初始化,19二进制位:10011 foo值:1100
std::bitset<4> foo(std:;string("0101")); //字符串初始化,字符串中必须只能含有‘0’/‘1’
2、常用操作:
位运算都可以用: 与、或、非、异或,左移,右移
foo&foo2
foo|foo2
~foo
foo^foo2
foo<<=2
foo>>=2
foo.size() 返回大小(位数)
foo.count() 返回1的个数
foo.any() 返回是否有1
foo.none() 返回是否没有1
foo.set() 全都变成1
foo.set(p) 将第p + 1位变成1
foo.set(p, x) 将第p + 1位变成x
foo.reset() 全都变成0
foo.reset(p) 将第p + 1位变成0
foo.flip() 全都取反
foo.flip(p) 将第p + 1位取反
foo.to_ulong() 返回它转换为unsigned long的结果,如果超出范围则报错
foo.to_ullong() 返回它转换为unsigned long long的结果,如果超出范围则报错
foo.to_string() 返回它转换为string的结果
b[pos] :访问b中在pos处的二进制位
b.test(pos) : b中在pos处的二进制位是否为1?
b.set(pos) 把b中在pos处的二进制位置为1
b.reset(pos) 把b中在pos处的二进制位置为0
例子
int main()
{
while(~scanf("%d",&q)){
bitset<64>ans(0);
while(q--){
scanf("%d",&fg);
if(fg == 0){
scanf("%d",&n);
cout<<ans[n]<<endl;
}else if(fg == 1){
scanf("%d",&n);
ans.set(n);
}else if(fg == 2){
scanf("%d",&n);
ans.reset(n);
}
else if(fg == 3){
scanf("%d",&n);
ans.flip(n);
}
else if(fg == 4){
if(ans.count() == 64)
printf("1\n");
else
printf("0\n");
}
else if(fg == 5){
if(ans.any())
printf("1\n");
else
printf("0\n");
}
else if(fg == 6){
if(ans.none())
printf("1\n");
else
printf("0\n");
}else if(fg == 7){
cout<<ans.count()<<endl;
}else{
cout<<ans.to_ullong()<<endl;
}
}
}
return 0;
}
string
数字的字典序比较
难点是将数字转化为字符,对于1位的加‘0’即可,但多位数的就不好处理,因此可以直接读入字符串。
int main()
{
string s1,s2,s;
cin>>n;
for(int i=0;i<n;++i)
cin>>s,s1 += s;
cin>>m;
for(int i=0;i<m;++i)
cin>>s,s2 += s;
if(s2>s1)
cout<<1<<endl;
else
cout<<0<<endl;
return 0;
}
map
map的基本操作函数
C++ Maps是一种关联式容器,包含“关键字/值”对
begin() 返回指向map头部的迭代器
clear() 删除所有元素
count() 返回指定元素出现的次数
empty() 如果map为空则返回true
end() 返回指向map末尾的迭代器
equal_range() 返回特殊条目的迭代器对
erase() 删除一个元素
find() 查找一个元素
get_allocator() 返回map的配置器
insert() 插入元素
key_comp() 返回比较元素key的函数
lower_bound() 返回键值>=给定元素的第一个位置
max_size() 返回可以容纳的最大元素个数
rbegin() 返回一个指向map尾部的逆向迭代器
rend() 返回一个指向map头部的逆向迭代器
size() 返回map中元素的个数
swap() 交换两个map
upper_bound() 返回键值>给定元素的第一个位置
value_comp() 返回比较元素value的函数
erase() 删除元素
- size_t erase( const key_type& key );
根据key来进行删除, 返回删除的元素数量,在map里结果非0即1 - iterator erase( iterator pos )
删除迭代器指向位置的键值对,并返回一个指向下一元素的迭代器 - iterator erase( const_iterator first, const_iterator last );
删除一定范围内的元素,并返回一个指向下一元素的迭代器
注意事项
- 使用
insert
方法插入的时候,如果键存在,不会覆盖原来的值,用数组的方式才可以。 - 还有一个很重要的点就是,如果访问了一个不存在的键,那么会返回0之后会自动创建这个键。
因此可以如下来解决
cin>>s;
if(!ans.count(s))
cout<<0<<endl;
else
printf("%d\n",ans[s]);
multimap
multimap容器保存的是有序的键/值对,但是可以保存重复的元素。multimap中会出现具有相同键值的元素序列。multimap大部分成员函数的使用方式和map相同。因为重复键的原因,multimap有一些函数的使用方式和map有一些区别。
访问元素
单个find()
multimap 的成员函数 find() 可以返回一个键和参数匹配的元素的迭代器。
std::multimap<std::string, size_t> people {{"Ann",25},{"Bill", 46}, {"Jack", 77}, {"Jack", 32},{"Jill", 32}, {"Ann", 35} };
std::string name {"Bill"};
auto iter = people.find(name);
if (iter ! = std::end (people))
std::cout << name << " is " << iter->second << std::endl;
iter = people.find ("Ann");
if (iter != std::end(people))
std::cout << iter->first << " is " << iter->second <<std::endl;
equal_range
如果我们想访问给定键对应的所有元素。成员函数 equal_range() 就可以做到这一点。它会返回一个封装了两个迭代器的 pair 对象,这两个迭代器所确定范围内的元素的键和参数值相等。例如:
auto pr = people.equal_range("Ann");
if(pr.first != std::end(people))
{
for (auto iter = pr.first ; iter != pr.second; ++iter)
std:cout << iter->first << " is " << iter->second << std::endl;
}
insert()
只能使用insert来插入元素
例如:
ans.insert(make_pair(s,x));
reverse
区间是左闭右开的。
reverse函数用于反转在**[first,last)**范围内的顺序(包括first指向的元素,不包括last指向的元素),reverse函数无返回值
rotate
template <class ForwardIterator>
void rotate (ForwardIterator first, ForwardIterator middle,
ForwardIterator last);
全排列函数
头文件:#include
函数模板:next_permutation(arr, arr+size);
函数模板:prev_permutation(arr, arr+size);
解释:arr为数组,size为数组长度。next_permutation(arr, arr+size);当有下一个较大值返回1,否则返回0,prev_permutation(arr, arr+size);当有上一个较小值返回1,否则返回0。例如:3 2 1,只有上一个较小值,没有下一个较大值。1 2 3只有下一个较大值,没有上一个较小值。2 1 3 的上一个较小值为 1 3 2,下一个较大值为 2 3 1.明白了吧!然后看下代码,怎么去用:
includes(子集)
在stl中有一个includes函数,对于vector来说,有v1和v2,如果判断v1里面的所有元素是否被v2所包含,则可以使用
includes(begin(v1),end(v1),begin(v2),end(v2))
如果v1包含v2则会返回true。
注意使用前提是必须先进行排序
即sort(begin(v1),end(v1)) sort(begin(v2),end(v2))
二分查找
首先数组必须是有序的!
1.binary_search()(查找某个值在数组中是否存在)
使用方法:binary_search(list,list+n,a)
list为数组,a为要查询的值,n为数组大小
binary_search返回的是真假值,就是它只判断这个数组中是否存在这个数;
2. lower_bound查找第一个大于或等于某个元素的位置
使用方法:lower_bound(list,list+n,a)
list为数组,n为数组大小,a为要查询的值
注意事项:lower_bound()返回的是指针,所以所以减去数组的指针就是int变量了