STL的常见用法

1.vector

#include <cstdio>
#include <vector>
using namespace std;
vector<int> arr;
int n;
int main()
{
    scanf("%d",&n);
    //为arr分配初始容量为n+1个元素
    //arr的下标为0-n
    //默认所有元素的值都是0
    arr.resize(n+1);
    int i;
    //为从下标为1至下标为n的元素赋值
    for(i=1;i<=n;i++)
    {
        scanf("%d",&arr[i]);
    }
    //输出从下标0到下标n的元素
    for(i=0;i<=n;i++)
    {
        if(i>0)
            printf(" ");
        printf("%d",arr[i]);
    }
    //输出的第一个元素值应该是0 因为第一个元素并未被赋值
    printf("\n");
    return 0;
}

另外,如果不知道容器中一共需要存储多少个元素,可以暂不指定大小,先往容器中插入,这样整个数组就是动态的。

#include <cstdio>
#include <vector>
using namespace std;
vector<int> arr;
int n;
int main()
{
    scanf("%d",&n);
    int temp;
    int i;
    //向容器中插入n个元素
    for(i=1;i<=n;i++)
    {
        scanf("%d",&temp);
        arr.push_back(temp);
    }
    //输出从下标0到下标n-1的元素
    for(i=0;i<n;i++)
    {
        if(i>0)
            printf(" ");
        printf("%d",arr[i]);
    }
    printf("\n");
    //获取动态数组的长度
    int len=arr.size();
    printf("The length of arr is %d.\n",len);
    return 0;
}

利用push_back(temp)向容器中添加值为temp的元素,利用size()获取动态数组当前存储元素的个数。

此外,pop_back()会删除动态数组中最后一个元素,如下所示(先往数组中添加n个元素,然后从后往前删除3个元素):

#include <cstdio>
#include <vector>
using namespace std;
vector<int> arr;
int n;
int main()
{
    scanf("%d",&n);
    int temp;
    int i;
    //向容器中插入n个元素
    for(i=1;i<=n;i++)
    {
        scanf("%d",&temp);
        arr.push_back(temp);
    }
    //输出从下标0到下标n-1的元素
    for(i=0;i<n;i++)
    {
        if(i>0)
            printf(" ");
        printf("%d",arr[i]);
    }
    printf("\n");
    for(i=0;i<3;i++)
    {
        arr.pop_back();
    }
    //获取动态数组的长度
    int len=arr.size();
    //输出动态数组中现存的所有元素
    for(i=0;i<len;i++)
    {
        if(i>0)
            printf(" ");
        printf("%d",arr[i]);
    }
    printf("\n");
    printf("The length of arr is %d.\n",len);
    return 0;
}

此外,容器可以在声明的同时指定元素个数,一般写在函数体中,如下所示:

#include <cstdio>
#include <vector>
using namespace std;
int n;
int main()
{
    scanf("%d",&n);
    //为arr分配初始容量为n+1个元素
    vector<int> arr(n+1);
    //arr的下标为0-n
    //默认所有元素的值都是0
    arr.resize(n+1);
    int i;
    //为从下标为1至下标为n的元素赋值
    for(i=1;i<=n;i++)
    {
        scanf("%d",&arr[i]);
    }
    //输出从下标0到下标n的元素
    for(i=0;i<=n;i++)
    {
        if(i>0)
            printf(" ");
        printf("%d",arr[i]);
    }
    //输出的第一个元素值应该是0 因为第一个元素并未被赋值
    printf("\n");
    return 0;
}

2.map

map<数据类型1,数据类型2>表示以数据类型1为下标类型的数组。什么意思呢,就是说数据类型1相当于数组的index,在数组int a[5]中,a[0]即第一个元素,0就是其index。那么在map<string,int> mp中,mp["张三"]=1,"张三"就是mp["张三"]的下标。

以下面一个例题为例:

输入一组姓名和一组查询,你需要做的是对每一个查询输出该姓名出现的次数。

输入格式:输入姓名的个数n,查询的个数m,随后n行输入n个姓名,随后m行输入m个需要查询出现次数的姓名。

输出格式:name共出现过num次,name为查询时输入的姓名,num为name出现的次数。

代码如下:

#include <cstdio>
#include <map>
#include <iostream>
using namespace std;
int n,m;
map<string,int> dp;
int main()
{
    //n为输入的姓名的个数
    //m为查询的个数
    cin>>n>>m;
    int i;
    string temp;
    for(i=0;i<n;i++)
    {
        cin>>temp;
        dp[temp]++;
    }
    for(i=0;i<m;i++)
    {
        cin>>temp;
        cout<<temp<<"共出现过"<<dp[temp]<<"次"<<endl;
    }
    return 0;
}

从上面的代码也可以看出,map<string,int> dp中未曾出现过的index其对应的元素值默认为0,比如index中已经出现过"张三",并令dp["张三"]=1,index中没有出现过李四,那么访问dp["李四"]时其值为0。同理map<int,int>中未曾出现过的index其对用的元素值默认也为0。

另外,map还有查找某个index存在与否的功能,将上面的例题稍加改变,最后查询结果为该姓名是否出现过,若出现过则显示Yes,未出现过则显示No。代码如下:

#include <cstdio>
#include <map>
#include <iostream>
using namespace std;
int n,m;
map<string,int> dp;
int main()
{
    //n为输入的姓名的个数
    //m为查询的个数
    cin>>n>>m;
    int i;
    string temp;
    for(i=0;i<n;i++)
    {
        cin>>temp;
        dp[temp]++;
    }
    for(i=0;i<m;i++)
    {
        cin>>temp;
        if(dp.find(temp)==dp.end())
        {
            cout<<"No"<<endl;
        }
        else
        {
            cout<<"Yes"<<endl;
        }
    }
    return 0;
}

dp.find(index)==dp.end()则表示未出现过以index为下标的元素。

3.set

set翻译成中文就是集合,学过高中数学的都知道,集合中是不允许相同元素存在的,因此在遇到有去重需求的问题时,采用set即可。set的底层使用了特殊的数据结构,可以快速有效地进行插入、删除和查找。

声明:

//声明
set<int> s;

插入操作:

//插入操作
int a=5;
s.insert(a);

获取set中元素的个数:

int num=s.size();

遍历:

#include <cstdio>
#include <set>
using namespace std;
int n;
set<int> s;
int main()
{
    //n为输入的整数的个数
    scanf("%d",&n);
    int i;
    int temp;
    for(i=0;i<n;i++)
    {
        scanf("%d",&temp);
        s.insert(temp);
    }
    //遍历
    for(set<int>::iterator it=s.begin();it!=s.end();it++)
    {
        if(it!=s.begin())
            printf(" ");
        int now=*it;
        printf("%d",now);
    }
    return 0;
}

查找(类似map):

if(s.find(temp)==s.end())
{
    printf("查找不到\n");
}
else
{
    printf("能查找到\n");
}

4.pair

pair翻译成中文就是“双”、“对”的意思,因此pair<数据类型1,数据类型2>就表示一对数据类型,pair可以作为元素插入到map中,当然也可以从map中读出pair,访问pair中前面的元素用first,访问pair中后面的元素用second。

//前面有过声明语句pos<string,int> ans;
for(map<string,int>::iterator it=ans.begin();it!=ans.end();it++)
{
    pair<string,int> now=*it;
    cout<<now.first<<" "<<now.second<<endl;
}

5.priority_queue

priority_queue翻译成中文是“优先队列”的意思,是STL中提供的模板,其底层是用堆实现的,顶部或者说优先出队的元素是所有元素中最大或者最小的,也就是对应着大顶堆和小顶堆,默认是大顶堆。将优先队列作大顶堆用还是作小顶堆用,是在声明时决定的。

声明一个大顶堆的语句如下:

//采用默认的优先队列声明方式即可
priority_queue<int> que;

或者如下声明,是在强调que是一个大顶堆:

priority_queue<int,vector<int>,less<int> > que;

声明一个小顶堆的语句如下:

priority_queue<int,vector<int>,greater<int> > que;

有两点需要注意,一是在声明大顶堆的时候用less<int>,而在声明小顶堆时用greater<int>;二是声明语句应避免出现两个'>'连用,如果连用编译器就会报错,中间需要用一个空格隔开。

获取堆顶元素:

int now=que.top();

将堆顶元素拿出:

que.pop();

获取堆中元素的个数:

int length=que.size();

判断堆是否已经为空:

bool isEmpty=que.empty();

6.<algorithm>

<algorithm>中提供了很多方法,可以用一行代码完成一些原本需要好多行代码才能完成的操作,可以减少代码量使逻辑更加清晰。

①fill

fill方法用于给数组中的元素指定初始值,可以是常规数组,也可以是vector,使用方法如下:

第一个参数是指定元素值的起始位置,第二个参数是指定元素值的中止位置的后一个元素的位置,第三个参数是指定值。

int arr[100];
int n=100;
fill(a,a+n,10);

以上代码是对数组arr中的全部元素赋初始值为10。

vector<int> arr;
arr.resize(100);
int n=100;
fill(arr.begin(),arr.end(),10);

以上代码也是对数组arr中的全部元素赋初始值为10。

②reverse

reverse翻译成中文是“翻转”的意思,功能是把数组中的元素倒过来放置,{1,2,3,4,5}反转完变成{5,4,3,2,1},操作对象可以是数组,也可以是vector,使用方法如下:

int arr[100];
int n=100;
//...经过一系列初始化...
reverse(arr,arr+n);

以上代码是将从地址为arr的元素起往后n个元素倒置。

vector<int> arr;
//...经过一系列初始化...
reverse(arr.begin(),arr.end());

以上代码是将数组arr中全部的元素倒置。

7.<cmath>

<cmath>是一个跟数学运算有关的库文件,里面提供了很多数学函数可以直接拿来用。

①向下取整、向上取整与四舍五入:

#include <cstdio>
#include <cmath>
using namespace std;
int n;
int main()
{
    scanf("%d",&n);
    double sum=0.0;
    int i;
    int temp;
    for(i=0;i<n;i++)
    {
        scanf("%d",&temp);
        sum+=temp;
    }
    printf("真实结果为%lf.\n",sum/n);
    int ans=floor(sum/n);
    printf("向下取整的结果为%d.\n",ans);
    ans=ceil(sum/n);
    printf("向上取整的结果为%d.\n",ans);
    ans=round(sum/n);
    printf("四舍五入的结果为%d.\n",ans);
    return 0;
}

以上代码描述的是一个求解平均数的程序,floor的中文意思是“地板”,对应向下取整;ceil的中文意思是“天花板”,对应向上取整;round的中文意思是“圆的”,四舍五入显得比较“圆滑”。

②pow函数

pow函数用于求a的b次方,pow(a,b),最原始的pow函数无论是参数还是返回值都是double类型的,因此最好在调用该函数的时候都先将类型转换成double再传入函数。我们都知道呈指数增长是间非常可怕的事情,在运算结果过大时,将其返回到long long int型变量中,其值可能为负数,如下所示:

#include <cstdio>
#include <cmath>
using namespace std;
int n;
int main()
{
    long long int a=10000000000;
    long long int b=10000000000;
    long long int ans=pow(a,b);
    printf("%lld\n",ans);
    return 0;
}

发布了84 篇原创文章 · 获赞 210 · 访问量 10万+

猜你喜欢

转载自blog.csdn.net/weixin_41676881/article/details/100522303