帅的STL学习笔记

关于 STL(标准模板库)

Standard Template Library,缩写:STL
STL 是 个 一C++ 软件库, 包含算法(里面algorithms)、容 器(containers)、函数(functions)、迭代器(iterators)

字符串(string)

创建string类型变量string s;
直接创建一个空的(大小为0)的string类型变量s
string s=*char; 创建string时直接用字符串内容对其赋值,注意字符串要用双引号""
strings(int n,char c); 创建一个string,由n个c组成,注意c是字符型要用单括号’’

读入string
cin>>s; 读入s,遇到空格或回车停止,无论原先s是什么内容都会被新读入的数据替代。
getline(cin,s); 读入s,空格也同样会读入,直到回车才会停止
输出string
cout<<s; 将s全部输出到一行(不带回车)

string中的函数

在这里插入图片描述

动态数组(vector)

vector 容器是 STL中最常用的容器之一,它和 array 容器非常类似,都可以看做是对 C++普通数组的“升级版”。不同之处在于,array 实现的是 静态数组(容量固定 的数组),而vector 实现的是一个动态数组,即可以进行元素的插入和删除,在此过程中,vector 会动态调整所占用的内存空间,整个过程无需人工干预。
在这里插入图片描述

//vector的创建
#include <bits/stdc++.h>
using namespace std;
int main()
{
    vector<int>v1;
    //创建一个存int类型的动态数组,int可以改成其它类型
    vector<double>v2{1,1,2,3,5,8};
    //创建一个存double类型的动态数组,长度为6,1 1 2 3 5 8分别存在v[0]~v[5]
    vector<long long>v3(20);
    //创建一个存long long类型的动态数组,长度为20,v[0]~v[19]默认为0
    vector<string>v4(20,"zzuacm");
    //创建一个存string类型的动态数组,长度为20,存的都是"zzuacm"
    vector<int>v5[3];
    //相当于存int的二维数组,一共3行,每行的列可变
    vector<vector<int> >v5{{1,2},{1},{1,2,3}};
    //存int的二维数组,行和列都可变,初始状态
    return 0;

基本操作

int main()
{
    vector<int>v;
    for(int i=1;i<=5;i++)
        v.push_back(i);//向动态数组中插入1~5
    cout<<v.size()<<endl;//输出数组的大小,有几个值
    for(int i=0;i<5;i++)
        cout<<v[i]<<" ";//输出v[0]~v[4],也就是1~5
    cout<<endl;
    v.clear();//将v清空,此时size为0
    v.resize(10);//为v重新开辟大小为10的空间,初始为0
    for(int i=0;i<v.size();i++)
        cout<<v[i]<<" ";//遍历每一个元素
    while(!v.empty())//当v还不空的话,去掉v的最后一个元素,等同于v.clear();
        v.pop_back();
    return 0;
}

vector插入、删除、遍历

int main()
{
    vector<int>v{0,1,2,3,4};
    v.erase(v.begin()+3);//删除v[3],v变为{0,1,2,4}
    v.insert(v.begin()+3,666);//在v[3]前加上666,v变成{0,1,2,666,4}
    v.front()=10;//将v[0]改成10,等同于v[0]=10;
    v.back()=20;//将v[4]改成20等同于v[v.size()-1]=20;
    for(int i=0;i<v.size();i++)
        cout<<v[i]<<" ";//使用下标访问的方法遍历v
    cout<<endl;
    for(auto i=v.begin();i!=v.end();i++)
        cout<<*i<<" ";//使用迭代器,从v.begin()到v.end()-1
    cout<<endl;
    for(auto i:v)//使用C++11新特性循环遍历v,如果需要改变i的值,还需要在前面加上&
        cout<<i<<" ";
    cout<<endl;
    return 0;
}

*关于迭代器(iterator)

vector::iterator it=v.begin();
auto it=v.begin();
二者等价

在这⾥ it 类似于⼀个指针,指向 v 的第⼀个元素
it 等价于 &v[0]
*it 等价于 v[0]
it 也可以进⾏加减操作,例如 it + 3 指向第四个元素
it++ 后it指向的就是v的第二个元素(v[1])了

队列(queue)

queue只能在容器的末尾添加新元素,只能从头部移除元素。
在这里插入图片描述

优先队列

priority_queue中出队顺序与插⼊顺序⽆关,与数据优先级有关,本质是一个堆
在这里插入图片描述

#include <bits/stdc++.h>
using namespace std;
int main()
{
    priority_queue<int> pq;//默认从大到小(大顶堆)
//    priority_queue<int,vector<int>,greater<int> >pq;从小到大(小顶堆)
    pq.push(1);
    pq.push(3);
    pq.push(2);
    while (!pq.empty())
    {
        cout << pq.top() << endl;//虽然进入队列的无序,但入队后自动排列,则top为最大元素
        pq.pop();
    }
    return 0;
}

在这里插入图片描述
priority_queue中存的元素如果是结构体这样无法进行比较的类型,必须要重载运算符<,相当于先使得优先队列中的元素可以进行比较再建立pq,否则直接建优先队列是会报错的
例如:

#include <bits/stdc++.h>
using namespace std;
struct Node{
    int x,y;
};
bool operator<(Node a,Node b){
    return a.x<b.x;
}
int main(){
    priority_queue<Node> pq;
    pq.push({1,3});
    pq.push({3,2});
    pq.push({2,1});
    while(!pq.empty())
    {
        cout<<pq.top().x<<' '<<pq.top().y<<endl;
        pq.pop();
    }
    return 0;
}

在这里插入图片描述

集合(set)

集合(set)是一种包含对象的容器,可以快速地(logn)查询元素是否在已知几集合中。
set 中所有元素是有序地,且只能出现⼀次,因为 set 中元素是有序的,所以存储的元素必须已经定义 过「<」运算符(因此如果想在 set 中存放 struct 的话必须⼿动重载「<」运算符,和优先队列一样)

与set类似的还有
multiset元素有序可以出现多次
unordered_set元素无序只能出现一次
unordered_multiset元素无序可以出现多次
博客推荐:
https://www.cnblogs.com/zyxStar/p/4542835.html
在这里插入图片描述

映射(map)

map 是照特定顺序存储由 key 和 value 的组合形成的元素的容器, map 中元素按照 key 进⾏排序,每个 key 都是唯⼀的,并对应着一个value,value可以重复
map的底层实现原理与set一样都是红黑树

与map类似的还有unordered_map,区别在于key不是按照顺序排序
博客推荐:
https://www.cnblogs.com/panweiwei/p/6657583.html

建立方法:

map<key, value> mp;
unordered_map<key, value>mp;

遍历方法:

for(auto i:mp)
    cout<<i.first<<' '<<i.second<<endl;
    

在这里插入图片描述

去重函数(unique)

unique(first, last):

▸ [first, last)范围内的值必须是一开始就提前排好序的
▸ 移除 [first, last) 内连续重复项
▸ 去重之后的返回最后一个元素的下一个地址(迭代器)

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int arr[]={3,2,2,1,2},n;
    sort(arr,arr+5);//需要先排序
    n=unique(arr,arr+5)-arr;//n是去重后的元素个数
    return 0;
}

二分函数(lower_bound/upper_bound)

lower_bound( )和upper_bound( )都是利用二分查找的方法在一个排好序的数组中进行查找的。

在从小到大的排序数组中,

lower_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于或等于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。

upper_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。

在从大到小的排序数组中,重载lower_bound()和upper_bound()

lower_bound( begin,end,num,greater() ):从数组的begin位置到end-1位置二分查找第一个小于或等于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。

upper_bound( begin,end,num,greater() ):从数组的begin位置到end-1位置二分查找第一个小于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。

int main()
{
    int arr[]={3,2,5,1,4};
    sort(arr,arr+5);//需要先排序
    cout << *lower_bound(arr,arr+5,3);//输出数组中第一个大于等于3的值
    return 0;
}

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值