类:
pair:
头文件:<utility>
定义:
是一个标准库类型。可以看作是有两个成员变量first和second的结构体,并且重载了<运算符(先比较first大小,再比较second大小)当我们创建一个pair时,必须提供两个类型
创建一个pair:pair<string,int> p
函数返回:make_pair(v1,v2)
函数返回由v1,v2初始化的pair,类型可以从v1,v2的类型推断出来
动态数组:(数组的下标从0开始)
头文件:<vector>
定义一个动态数组:vector<int> a
插入元素:a.push_back()
获取长度:a.size()
删除元素:a.pop_back()(只能在末端操作)
迭代器:
std: :vector<int>: :inerator it //it只能读写vector<int>的元素
std: :vector<int>: :const_inerator it //it只能读vector<int>的元素,不可以修改vector<int>中的元素
for( it = vector.begin(); it != vector.end(); it++ )cout<<*it<<endl;
for( std::vector<int>::reverse_iterator it = v.rbegin(); it!=v.rend();it++ )cout<<*it<<endl;
清空:clear()
只会清空数据,不会清空内存
#include<iostream>
using namespace std;
int main(){vector<int> a;//[]//插入元素a.push_back(1);//[1]a.push_back(2);//[1,2]a.push_back(3);//[1,2,3]//获取长度for(int i=0;i<a.size();i++){cout<<a[i]<<endl;}//修改元素a[0]=2;//[2,2,3]//删除元素a.pop_back();//[2,2]a.pop_back();//[2]return 0;
}
高级用法:
动态数组不仅仅可以存储基本的数据类型,还能存储自定义数据类型,比如结构体
#include<iostream>
#include<vector>
using namespace std;
struct student{string name;int age;
};
int main(){vector<student> class1;//创建动态数组:班级 student stu1,stu2;//学生1,学生2 stu1.name="小明";stu1.age=13;stu2.name="小红";stu2.age=14;//将两个学生导入到班级数组里面去 class1.push_back(stu1);class1.push_back(stu2);for(int i=0;i<class1.size();i++){cout<<"第"<<i+1<<"名学生:";cout<<"姓名:"<<class1[i].name<<endl;cout<<"年龄:"<<class1[i].age<<endl;}return 0;
}
构造函数:
批量初始化:vector<int> a(初始化动态数组的长度,初始的数组里面每个元素的值)
#include<iostream>
#include<vector>
using namespace std;
int n=10;
vector<int> a(n,1);
int main(){for(int i=0;i<a.size();i++){cout<<a[i]<<endl;}return 0;
}
二维动态数组:vector <vector<int> > vec2
注意:<int> >中间有一个空格,这个空格一定要加上,否则在一些老版本的编译器上不能通过编译
#include<iostream>
#include<vector>
using namespace std;
int n=5;
vector<vector<int> > a;
int main(){for(int i=0;i<n;i++){vector<int> x(i+1,1);a.push_back(x); } for(int i=0;i<n;i++){for(int j=0;j<a[i].size();j++){cout<<a[i][j]<<" ";}cout<<endl;}/*11 11 1 11 1 1 11 1 1 1 1*/return 0;
}
二维动态数组的每一维长度都可以不一样,可以是任意形状的。借助构造函数,我们可以快速的构造一个n行m列的动态数组,每个元素的初始值为0:vector<vector<int> > vec2(n,vector<int>(m,0))
#include<iostream>
#include<vector>
using namespace std;
//定义一个n行m列的二维动态数组
//先要初始化,不能为空的时候使用
int n=10,m=5;
vector<vector<int> >vec2(n,vector<int>(m,0));
int main(){return 0;
}
#include<iostream>
#include<vector>
using namespace std;
vector<vector<int> > v2d;
int main(){for(int i=0;i<5;i++){v2d.push_back(vector<int>());}for(int i=0;i<v2d.size();i++){for(int j=0;j<=i;j++){v2d[i].push_back((i+1)*(j+1));}}for(int i=0;i<v2d.size();i++){for(int j=0;j<=i;j++){cout<<i+1<<"*"<<j+1<<"="<<v2d[i][j]<<" ";}cout<<endl;}return 0;
/*
1*1=1
2*1=2 2*2=4
3*1=3 3*2=6 3*3=9
4*1=4 4*2=8 4*3=12 4*4=16
5*1=5 5*2=10 5*3=15 5*4=20 5*5=25
*/
}
集合set:(去除重复)
头文件:<set>
定义一个集合:set<string> a
插入元素:a.insert(" ")
删除元素:erase()
获取元素个数:size()
清空:clear()
clear()会帮忙清空集合,同时也会清空set所占的内存
判断元素是否存在:count()
如果集合中存在我们要查找的元素,返回1,否则会返回0
#include<iostream>
#include<set>
#include<string>
using namespace std;
set<string> a;
int main(){a.insert("China");//{"China"}a.insert("America");//{"Chinea","America"}a.insert("France");//{"China","America","France"} if(a.count("China")){cout<<"China belong to a"<<endl; }return 0;
}
迭代器:set<string>: :iteratoe it
#include<iostream>
#include<set>
#include<string>
using namespace std;
set<string> country;
int main(){country.insert("China");//{"China"}country.insert("America");//{"Chinea","America"}country.insert("France");//{"China","America","France"} //声明一个迭代器 set<string>::iterator it;for(it=country.begin();it!=country.end();it++){cout<<*it<<" ";} cout<<endl;return 0;
}
运算符重载(重新定义小于符号):operator<
set经常会配合结构体来使用,用set来存储结构体和vector有些区别。正如我们前面所说,set是需要经过排序的。系统自带的数据类型有默认的比较大小的规则,而我们自定义的结构体,系统是不可能知道这个结构体比较大小的方式的。所以我们需要用一种方式来告诉系统怎么比较这个结构体的大小。
#include<iostream>
#include<set>
#include<string>
using namespace std;
struct a{int x,y;bool operator<(const a&rhs) const{ //operator< 为运算符重载 if(x==a.x){return y<rhs.y;}else{return x<rhs.x;}}//这里规定的排序方式为,优先按照x从小到大排序,如果x相同,再按照y从大到小排序。//经过了<运算符重载的结构体,我们就可以比较两个Node对象的大小了,因此可以直接存储在set里
};
int main(){return 0;
}
#include<iostream>
#include<set>
#include<string>
using namespace std;
struct Point{ //创建一个结构体int x, y;bool operator<(const Point&rhs) const{ //进行运算符重载if(x==rhs.x){ //如果x相同则对y进行排序return y<rhs.y;}else{return x<rhs.x; //x小的排在前面}}
};
set<Point> v; //定义一个结构体类型的集合v
int main(){int n;cin>>n;for(int i=0;i<n;i++){Point temp;cin>>temp.x>>temp.y ;v.insert(temp); }for(set<Point>::iterator it=v.begin();it!=v.end();it++){ //迭代器进行遍历我们的集合cout<<it->x<<" "<<it->y<<endl; //->为指针的用法}return 0;
}
注意:
1.如果集合中已经存在了某个元素,再次插入不会产生任何效果,集合中是不会出现重复元素的
2.set是从小到大遍历的,也就是说set会帮我们排序
映射:map()
定义:将关键字集合(key)映射到值集合(value)
头文件:<map>
构造一个映射:map<类型1,类型2> m //将类型1映射到类型2
插入一对映射:insert()
检测是否存在(存在:1,否则:0):count()
访问及修改映射:dict["Tom"]=1
迭代器:map<string,int>: :iterator it
访问映射的长度:size()
注意:在C++遍历map是按照关键字从小到大遍历的
#include<map>
#include<string>
#include<utility>
using namespace std;
pair<string,int> a;
map<string,int> dict;
int main(){dict.insert(make_pair("Tom",1));//{"Tom"->1} //插入元素dict.insert(make_pair("Jone",2));//{"Tom"->1,"Jone"->2}dict.insert(make_pair("Mary",1));//{"Tom"=>1,"Jone"->2,"Mary"->1} if(dict.count("Mary")){ //判断元素是否存在cout<<"Mary is in class"<<dict["Mary"]<<endl;dict["Mary"]=5; }for(map<string,int>::iterator it=dict.begin();it!=dict.end();it++){//迭代器进行遍历cout<<it->first<<" is in class"<<it->second<<endl; }dict.clear(); //清空该映射return 0;
}
栈:
特点:只能从一个方向处理数据
头文件:<stack>
创造空栈:stack<int> s
判断栈是否为空(为空返回true,否则返回false): s.empty()
返回栈中元素的个数,即栈的长度:s.size()
获取栈顶的元素:s.top()
插入元素x为新的栈顶元素:s.push()
删除s栈顶元素:s.pop();
注:切记不要在栈为空的时候访问top会出段错误!!!
队列:
头文件:<queue>
特点:
- 只能访问表的首元素并删除首元素
- 只能在表的最后端插入元素
- 最前端的叫做队头
- 最后端的叫做队尾
构造一个队列:queue<int> a
入队:a.push()
出队:a.pop()
判断队列是否为空:a.empty()
访问队首元素:a.front()
访问队列的长度:a.size()
清空队列:一个一个地清空
//清空队列while(!a.empty()){a.pop();}