【STL】常用STL容器(相关函数+应用场景+注意点)

本文记录一些常用的stl容器
能力有限,涵盖的应用场景和注意点不一定全,刷题遇到了再补充,当然,真遇到了多半还是靠经验随机应变- -

vector容器

1.定义: vector < typename > v (len , value);
len为v的长度,value为v中元素的初始值,可省略vlaue或(len,value)

2.头文件:#include < vector >

3.相关函数: 以vector < int > v为例(只记录一些常用的,下同)

函数用途
v.begin()返回数组的第一个元素的迭代器
v.end()返回数组的最后一个元素的下一个元素的迭代器,元素不存在
v.rbegin()返回数组的最后一个元素的迭代器
v.push_back(x)数组末尾插入x
v.erase( v.begin()+i )删除下标为 i 的元素
v.at(i)访问下标为 i 的元素
v[i]访问下标为i的元素
v.size()返回数组长度
v.clear()删除所有元素
v.empty()判断是否为空,是则返回true

代码示例:

#include <iostream>
#include <vector>
using namespace std;

int main(){
    vector<int> v;
    v.push_back(1);
    v.push_back(2);
    v.push_back(3);
    cout<<*v.begin()<<" "<<*v.end()<<" "<<*v.rbegin()<<endl;
    cout<<"数组长:"<<v.size()<<endl;
    v.erase(v.begin()+1);
    cout<<"数组长:"<<v.size()<<endl;
    cout<<v.at(0)<<" "<<v[1]<<endl;
    v.clear();
    cout<<"数组长:"<<v.size();
    return 0;
}

运行结果:
运行结果1
4.应用场景:
1)基本上用到数组就可以用vector平替,操作比静态array灵活,最大缺点就是内存占用比array要大

5.注意点:
1)v.begin()等返回的是指针,要得到值需要用取值符号*,或者直接下标||at访问;
2)删除某一位置的元素前先查看一下是否越界,避免造成程序崩溃


map和unordered_map

1.定义: map < typename , typename > m;

2.头文件:#include < map >

3.相关函数: 以map < string , int > m为例(unordered_map类似)

函数用途
m[key]=value插入键值对{key:value}
m[key]返回key对应的value
m.begin()返回m的第一对键值对的迭代器
m.end()返回m的最后一个键值对的下一个的迭代器,无指向内容
m.rbegin()返回m的最后一个键值对的迭代器
m.find(key)查找键为key的键值对,若没有找到则返回m.end()
m.erase(key)把key对应的那条键值对删去,key存在则返回1,不存在则返回0
m[key]->first or m[key]->second返回key or 返回key的value

代码示例:

#include <iostream>
#include <map>
#include <unordered_map>
using namespace std;

int main(){
    map<string,int> m;
    unordered_map<string,int> um;
    cout<<"-----map-----"<<endl;
    m["aaa"]=1;
    m["bbb"]=5;
    m["ddd"]=6;
    m["eee"]=7;
    for(auto it:m){
        cout<<it.first<<" "<<it.second<<endl;
    }
    cout<<"删除aaa和ccc:"<<m.erase("aaa")<<" "<<m.erase("ccc")<<endl;
    cout<<m.begin()->first<<" "<<m.rbegin()->first<<endl;
    cout<<"-----unordered_map-----"<<endl;
    um["aaa"]=1;
    um["bbb"]=5;
    um["ddd"]=6;
    um["eee"]=7;
    for(auto it:um){
        cout<<it.first<<" "<<it.second<<endl;
    }
    return 0;
}

运行结果:
运行结果2

4.应用场景:
1)用于快速找到某一key对应的value;
2)因为map的顺序是key的升序排列,所以题目中如果对排序有一定要求也可以使用;
3)unordered_map是无序的,如果题目对于顺序没有要求,只是快速查找,则unordered_map要更高效;
4)存类似student的结构体时也可以用map,key为学生的唯一id,value为student结构体,这样可以快速找到某一学生对应的信息。

5.注意点:
1)first 和 second 注意 . 和 -> 的使用,不过一般系统会报错提醒;


set和multiset (补:priority_queue

1.定义: set < typename > st;

2.头文件:#include < set >

3.相关函数: 以set < int > st为例(multiset类似)

函数用途
st.insert(x)插入值x
st.begin()返回st的第一个元素的迭代器
st.end()返回st的最后一个元素的下一个的迭代器,无指向内容
st.rbegin()返回st的最后一个元素的迭代器
st.erase(x)若x为值,则删除值为x的元素;若x为迭代器,删除迭代器指向的值
st.find(x)返回值为x的迭代器,没找到则返回st.end()
st.lower_bound(x)返回第一个大于等于x的迭代器
st.upper_bound(x)返回最后一个大于等于x的定位器

代码示例:

#include <iostream>
#include <set>
using namespace std;

int main(){
    set<int> st;
    multiset<int> mst;
    cout<<"-----set-----"<<endl;
    st.insert(11);
    st.insert(23);
    st.insert(5);
    st.insert(5);
    for(auto it:st){
        cout<<it<<endl;
    }
    st.erase(5);
    cout<<"删除后最小值为:"<<*st.begin()<<endl;
    cout<<"-----multiset-----"<<endl;
    mst.insert(11);
    mst.insert(23);
    mst.insert(5);
    mst.insert(5);
    mst.insert(5);
    for(auto it:mst){
        cout<<it<<endl;
    }
    cout<<"第一个大于等于11:"<<*mst.lower_bound(11)<<endl
        <<"最后一个大于等于11:"<<*mst.upper_bound(11)<<endl;
    mst.erase(mst.begin());
    cout<<"迭代器删除,删除一个5后:"<<endl;
    for(auto it:mst){
        cout<<it<<endl;
    }
    mst.erase(5);
    cout<<"值删除,删除全部5后:"<<endl;
    for(auto it:mst){
        cout<<it<<endl;
    }
    return 0;
}

运行结果:
运行结果3

4.应用场景:
1)需要对数据进行排序时使用;
2)快速找第一或最后的某个范围内的数时,lower_bound()和upper_bound()用的是二分,因此更高效

5.注意点:
1)找出第n小的数的时候,不要用set!用也可以但是不如sort排序数组代码块来的容易,经常被这个坑并且屡教不改= =
2)set不允许重复,multiset允许重复,因此要仔细分析题目,到底是需要某个数重复还是不需要;
3)multiset删除的时候注意用法,set删一个就是全删了,multiset删可能需要删一个,也可能需要全删

补++:

priority_queue(补充的简单讲讲)

1.头文件: 在< queue >头文件中,但是因为都涉及到排序因此放在这里一起对比了
2.相关函数: 以priority_queue < int > q为例

函数用途
q.push(x)入队,自动排序,大根堆降序排列
q.top()返回队首元素,即最大的元素
q.pop()队首元素出队
q.empty()判断是否为空,是则返回true

4.应用场景:
1)仅对最大值(可修改为最小)做改动,对其他元素没有要求

5.注意点:
1)优先队列只能用top访问队首元素,不可以访问其他元素,底层逻辑是大根堆


stack

1.定义: stack < typename > s;

2.头文件:#include < stack >

3.相关函数: 以stack < int > s为例

函数用途
s.push(x)入栈,末位插入x
s.pop()出栈,弹出栈顶元素
s.empty()判断是否为空,是则返回true
s.top()返回栈顶元素的值

代码示例:

#include <iostream>
#include <stack>
using namespace std;

int main(){
    stack<int> s;
    s.push(1);
    s.push(2);
    s.push(3);
    cout<<s.top()<<endl;
    cout<<"弹出栈顶元素:";
    while(!s.empty()){
        cout<<s.top()<<" ";
        s.pop();
    }
    return 0;
}

运行结果:
运行结果4
4.应用场景:
1)只允许一端出入的类型,典型的比如单调栈类型题

5.注意点:
1)用法比较简单,选定用栈做题后没什么需要注意的,此条待补充。


queue

1.定义: queue < typename > q;

2.头文件:#include < queue >

3.相关函数: 以queue < int > q为例

函数用途
q.push(x)入队,队尾插入x
q.pop()删除队头元素
q.front()返回队头元素
q.back()返回队尾元素
q.empty()判断队伍是否为空,是则返回true

代码示例:

#include <iostream>
#include <queue>
using namespace std;

int main(){
    queue<int> q;
    q.push(1);
    q.push(2);
    q.push(3);
    cout<<q.front()<<" "<<q.back()<<endl;
    cout<<"出队:";
    while(!q.empty()){
        cout<<q.front()<<" ";
        q.pop();
    }
    return 0;
}

运行结果:
运行结果5

4.应用场景:
1)先入先出的类型题,做的比较少暂时没遇到多少典型

5.注意点:
1)栈和队列的插入和删除,因为限定了一端所以与其他的稍有不同,但总体来说主要是选定问题,选定用栈或队列解题后其函数用法都比较简单,同栈一样,此条待补充

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值