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;
}

歡迎大家關注/訂閱我的微信公衆號Code Art Online,我會在我的公衆號分享個人見聞,發現生活趣味;這裏不僅有0和1,還有是詩和遠方↓↓↓

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章