C++中常用容器介绍
1.vector
1.1 insert 与push_back()函数的区别
The biggest difference is their functionality. push_back always puts a new element at the end of the vector and insert allows you to select new element’s position.
insert()
的使用方法
void test7(){
vector<int> a ;
a.insert(a.begin(), 1);
a.insert(a.begin(),2) ;
a.insert(a.begin(),3) ;
a.insert(a.end(),4) ;
for(vector<int>::iterator it= a.begin();it!=a.end();it++){
cout << *it <<" ";
}cout <<"\n";
}
int main(){
test7();
}
执行结果
2.map
2.1 例一
- 定义一个常见类型的map
- 遍历输出
#include <stdio.h>
#include <map>
using namespace std;
int main(){
map<char,int> mp;
mp['m'] = 20;
mp['a'] = 12;
for(map<char ,int> :: iterator it = mp.begin();it!=mp.end();it++){
printf("%c %d\n",it->first,it->second);
}
map<char ,int > :: iterator it = mp.find('b');
printf("%c %d\n",it->first,it->second);
return 0;
}
#include <iostream>
#include <cstdio>
#include <map>
#include <string>
using namespace std;
int main(){
map<string , int > mp;
int i ;
string str1,str2;
getline(cin,str1);
mp[str1] = 1;
getline (cin ,str2);
mp[str2] = 2;
map<string ,int> :: iterator it = mp.begin();
for(;it!=mp.end();it++){
cout<<it->first<<" "<<it->second<<endl;
}
}
2.2 例二
- map的值(value)不再是常见的类型,而是一个复合类型
#include <iostream>
#include <cstdio>
#include <map>
#include <string>
#include <set>
using namespace std;
int main(){
map<string ,set<int> > mp;
for(int i = 0; i < 10;i++){
mp["lius"].insert(i);
}
set<int>::iterator it = mp["lius"].begin();
for(;it!=mp["lius"].end();it++){
printf("%d ",*it);
}
}
执行结果如下:
2.3 例三
- map中未找到的键,所对应的指针指向最后,输出的值是0。
- 若有重复键的值输入,则会造成值的覆盖。
#include <cstdio>
#include <map>
using namespace std;
int main(){
map< int , int > mp;
mp[1] = 11;
mp[2] = 12;
mp[3] = 13;
map<int,int>::iterator it = mp.find(1);
printf("%d ",it->second);
it = mp.find(4);
printf("%d ",it->second);
}
#include<cstdio>
#include<cstring>
#include<map>
#include<string>
#include<algorithm>
#include<iostream>
using namespace std;
int main(){
map<int,string> result;
result[1111]="first";
result[1111]="second";
for(map<int,string> :: iterator it=result.begin(); it!=result.end(); it++){
printf("%d\n",it->first);
cout << it->second;
}
}
输出结果:
1111
second
2.4 自定义键值对
当自带类型无法满足映射时,就可以自定义结构体类型,用于map的键值类型。
- 自定义结构体
自定义结构体常常伴随着运算符的重载,因为在map中,键是必须按照大小顺序来排序的,下面的Edge
不仅给出了结构体成员,还有<
的重载【重要!】。
struct Edge{
int left,right;
bool operator<(const Edge &e1) const{
if(this->left == e1.left )
return this->right < e1.right;
return this->left < e1.left;
}
};
- 使用结构体
void test3(){
map<Edge,int> ma;
int n;
cin >> n;
int w;
for(int i = 0;i< n;i++){
Edge edge;
cin >> edge.left >> edge.right >> w;
ma[edge] = w;
}
for(map<Edge,int>::iterator it = ma.begin();it!=ma.end();it++){
cout << "("<<it->first.left <<","<<it->first.right<<") = "<<it->second <<"\n";
}
}
3.stack
#include <cstdio>
#include <stack>
using namespace std;
int main(){
stack<int> st;
int i ;
for(i = 0;i< 10;i++){
st.push(i);
}
for(i = 0;i< 10;i++){
printf("%d ",st.top());//取栈顶
st.pop();//删除栈顶
}
}
4.queue
#include <cstdio>
#include <queue>
#include <algorithm>
using namespace std;
int main(){
queue<int> qu;
int i ;
for(i = 0;i< 10;i++){
qu.push(i);
}
while(!qu.empty()){
printf("%d ",qu.front());
qu.pop();
}
}
/**
注
1.front()函数返回的是队首元素
2.empth()函数判断是否为空,若为空,则返回1;否则返回0
3.pop()函数删除队首
4.push()函数入队
*/
4.priority_queue
4.1 存储自带类型的数据
使用下面这种默认的构造方法,使用 priority_queue
void test9(){
//默认是大根堆(没错),priority_queue 的实现方式就是堆
priority_queue<int> pq;
pq.push(1);
pq.push(2);
pq.push(3);
while(!pq.empty()){
cout << pq.top()<<" ";
pq.pop();
}
}
执行结果如下:
但是如果我们想要小的数排在前面,大的数排在后面该怎么做?
需要注意的地方有如下几个:
- 1. 改变整型数据的排序时,不仅要说明是用
greater<int>
还是用less<int>
[就是默认的从大到小排序],还需要说明底层用什么类型的容器存储数据【比如这里使用的就是vector存储数据】。
void test9(){
priority_queue<int,vector<int>, greater<int> > pq;
pq.push(1);
pq.push(2);
pq.push(3);
while(!pq.empty()){
cout << pq.top()<<" ";
pq.pop();
}
}
执行结果如下:
4.2 存储自定义类型
-
1.定义结构体
-
2. 自定义排序规则
使用priority_queue
时,因为其内部的排序规则不一定适合我们,所以当我们将一个自定义的结构体放入到优先队列中,就需要重载<
运算符,这样就可以按照任何顺序输出。下面给出一个例子。
给出一个二维数组,其含义是该点坐标上的山丘的高度。现在我们想按照高度从大到小排序,该怎么做? -
定义结构体
typedef struct{
int x,y,high;//坐标值;高度
}Node;
- 自定义排序规则【重点!!!】
//高度大的在前
bool operator <(const Node& n1, const Node &n2) {
return n1.high < n2.high;
}
- 完整代码
#include<cstdio>
#include<queue>
#include<iostream>
using namespace std;
const int maxN = 705;
int vis[maxN][maxN],gra[maxN][maxN];//该坐标点是否已经访问过了; 用以描述图形
int n,m;
typedef struct{
int x,y,high;//坐标值;高度
}Node;
//高度大的在前
bool operator <(const Node& n1, const Node &n2) {
return n1.high < n2.high;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
priority_queue<Node> pq;
cin >> n >> m;
Node info;
for(int i = 0;i<n;i++){
for(int j = 0;j<m;j++){
cin >> gra[i][j];
info.x = i, info.y = j,info.high = gra[i][j];
pq.push(info);
}
}
Node temp;
int cnt = 0;
while(!pq.empty() && cnt < 5){
cnt ++;
temp = pq.top();
cout << "("<<temp.x << temp.y << ")"<<temp.high<<"\n";
pq.pop();
}
}
使用如下测试用例:
4 7
4 3 2 2 1 0 1
3 3 3 2 1 0 1
2 2 2 2 1 0 0
2 1 1 1 1 0 0
执行结果如下: