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,還有是詩和遠方↓↓↓