目录
一、vector容器---动态数组
1.为什么要引进动态数组?
2.引用库
3.构造一个动态数组
4.一些增删查改动态数组的方法
5.使用基础的vector
6.构造函数
7.二维动态数组
二、set()容器---集合
1.构造一个集合
2.方法
2.1插入元素
2.2判断元素是否存在
2.3迭代器
2.4清空
2.5基本应用
3.运算符重载
4.用set来存储一个二维坐标系上的点的集合---关于结构体
三、map()容器---映射
1.构造一个映射
2.基本应用
3.map套set
4.map套用map
四、锯齿矩阵
一、vector容器---动态数组
1.为什么要引进动态数组?
(1)有些时候想开一个数组,单数却不知道应该开多大长度的数组合适,因为我们需要用到的数组可能会根据情况变动。这时候我们就需要用到动态数组。
(2)c++中的动态数组写作vector
2.引用库
c++中vector的实现在一个<vector>头文件中,在代码开头引入这个头文件,并在引入所有头文件之后加上一句using namespace std
#include<vector>
using namespace std;
int main(void)
{return 0;
}
3.构造一个动态数组
vector<T> vec 其中T是我们数组要存储的数据类型:int float double都可以
4.一些增删查改动态数组的方法
vector方法总结:
push_back:在末尾加入一个元素
pop_back:删除动态数组的最后一个元素
size:获取长度
clear:清空 但是只是清空vector,并不会清空开的内存。用一种方法可以清空内存://vector<int> v;
vector<int>().swap(v);
5.使用基础的vector
#include<iostream>
#include<vector>
using namespace std;
int main(void)
{vector<int> v;for (int i = 1;i <= 10; i++){v.push_back(i * i);}for (int i = 0; i < v.size(); i++){cout << v[i] << " ";}cout << endl;return 0;
}
6.构造函数
引言:我们都知道通过push_back()来向动态数组添加一个元素。如果我们需要一个长度为n的,全是1的动态数组,用for循环来写就小题大作了。so我们可以通过一个构造函数快速构建这样的一个动态数组。所谓构造函数,就是我们在定义一个对象的时候就可以给它赋值
#include<iostream>
#include<vector>
using namespace std;
int main(void)
{int n = 10;vector<int> vec(n, 1);//构造函数,第一个参数是初始的动态数组的长度,第二个参数表示初始的数组里面每个元素的值。//如果不传入第二个参数,那么初始的值都是0//通过合理的使用构造函数,可以减少代码量for (int i = 0; i < n; i++){cout << vec[i] << " ";}return 0;
}
7.二维动态数组
vector<vector<int> >vec2 这样定义了一个二维动态数组 注意:<int> >中间有一个空格,这个空格一定要加上,否则这些老版本的编译器不能通过编译
#include<iostream>
#include<vector>
using namespace std;
int main(void)
{int n = 5;vector<vector<int> > vec2;for (int i = 0; i < n; i++){vector<int> x(i + 1, 1);vec2.push_back(x);}for (int i = 0; i < 5; i++){for (int j = 0; j < vec2[i].size(); j++){cout << vec2[i][j] << " ";}cout << endl;}return 0;
}
二维动态数组的每一维的长度都可以不一样,可以是任意形状的。借助构造函数,我们可以快速构造一个n行m列的动态数组,每个元素的初始值是0:
vector<vector<int> > vec2(n,vector<int>(m,0));
下面我们用二维动态数组来记录一个1到5的乘法表
#include<iostream>
#include<vector>
using namespace std;
int main(void)
{vector<vector<int> > vec2;for (int i = 0; i < 5; i++){vec2.push_back(vector<int>());}for (int i = 0; i < 5; i++){for (int j = 0; j <= i; j++){vec2[i].push_back((i + 1) * (j + 1));}}for (int i = 0; i < vec2.size(); i++){for (int j = 0; j <= i; j++){cout <<j+1<<"*"<<i+1<<"="<< vec2[i][j] << "\t";}cout << endl;}return 0;
}
二、set()容器---集合
1.构造一个集合
c++中直接构造一个set的语句为:set<T> s . 这样我们定义了一个名为s的、储存T类型数据的集合,其中T是集合要储存的数据类型。初始的时候s是空集合。比如
set<int> aa,set<string> bbb等等
2.方法
2.1插入元素
c++中用insert()函数向集合中插入一个新的元素。注意如果集合中已经存在了某个元素,再次插入不会产生任何效果,集合中是不会出现重复元素的。
2.2判断元素是否存在
c++中如果你想知道某个元素是否在集合中出现,你可以直接用count()函数。如果集合中存在我们要查找的元素,返回1,否则返回0。
2.3迭代器
.遍历元素:
c++通过迭代器可以访问集合中的每个元素,迭代器就好像一根手指指向set中的某个元素。通过操作这个手指,我们可以改变它指向的元素
通过*(解引用运算符,不是乘号的意思)操作可以获取迭代器指向的元素。
set<T>::iterator it就定义了一个迭代器it 注意:begin函数返回容器的其实元素的迭代器,end函数返回容器的尾后迭代器
2.4清空
c++中调用clear()函数就可清空set,同时会清空set占用的内存
2.5基本应用
#include<set>
#include<iostream>
using namespace std;
int main(void)
{set<string> country;country.insert("China");country.insert("American");country.insert("France");set<string>::iterator it;for (it = country.begin(); it != country.end(); it++){cout << *it << endl;}cout << endl;country.erase("American");//erase()函数用于删除集合中的元素country.erase("England");for (it = country.begin(); it != country.end(); it++){cout << *it << endl;}cout << endl;if (country.count("China")){cout << "China in set" << endl;}country.clear();return 0;
}
3.运算符重载
运算符重载:
set经常会配合结构体来使用,用set来存储结构体和vector有些区别,正如我们前面所说的那样,set是需要经过排序的,系统自带的数据类型有默认的比较大小的规则,而我们自定义的结构体,系统是不可能知道这个结构体比较大小的方式的
所以我们需要一种方式来告诉系统怎样比较这个结构体的大小。其中一种方法叫做运算符重载,我们需要重新定义小于符号。
struct Node
{int x, y;bool operator<(const Node& rhs) const{if (x == rhs.x){return y < rhs.y;}else{return x < rhs.x;}}
};
4.用set来存储一个二维坐标系上的点的集合---关于结构体
#include<iostream>
#include<set>
using namespace std;
struct Point
{int x, y;bool operator<(const Point& rhs)const{if (x == rhs.x){return y < rhs.y;}else{return x < rhs.x;}}
};
int main(void)
{int n;set<Point> v;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;
}
三、map()容器---映射
映射:是指两个集合之间的元素的相互对应关系。通俗的说,就是一个元素对应另外一个元素。比如有一个姓名的集合{“tom”,“jone”},班级集合{1,2}。姓名与班级之间可以有如下的映射关系:
class{"tom"}=1,class{"jone"}=2,class{"Mary"}=1;
我们称其中的姓名集合为关键字集合(key),班级集合为值集合(value)
c++中我们常用的映射是map
1.构造一个映射
在c++中,我们构造一个map的语句为:map<T1,T2> m。这样我们定义了一个名为m的从T1类型到T2类型的映射。初始的时候m是空映射。比如map<string,int> m构建一个字符串到整数的映射,这样我们可以把一个字符串和一个整数关联起来
2.基本应用
#include<map>
#include<iostream>
using namespace std;
int main(void)
{map<string, int> dict;dict["Tom"] = 1;dict["Jone"] = 2;dict["Mary"] = 1;if (dict.count("Mary")){cout << "Mary is 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;}return 0;
}
3.map套set
(1)map套用set:为了帮助理解,我们举一个生活中实际例子。全校有很多班级,每个班级每个人都会有中文名。现在我们需要用一种方式来记录全校的同学的名字。如果直接用一个set记录,对于重名的同学,那么就没办法分辨了
我们可以把全校的班级进行编号,对每个班级建立一个set,也就是每个班级都映射成一个set,这样就能分辨不同班级的同名同学了
用法:map<int,set<string> > s就定义上面描述的数据结构,和二维的vector一样,两个> >中间的空格不能少
这样我们就可以进行插入和查询了,比如对2班的yuhaoran同学,我们s[2].insert("yuhaoran").然后查询yuhaoran是不是一个2班的人,是s[2].count("yuhaoran").然后还可以把他从二班删除,s[2].erase("yuhaoran")
4.map套用map
上面的结构没有办法解决同伴同名的情况。实际上,如果同班同名,单单通过名字本身是无法分辨的,需要通过其他特征来分辨。所以为了简单起见,我们只需要记录每个班级同名的人的个数
map<int,map<string,n> > s。2班有一个yuhaoran,s[2]["yuhaoran"]++ 。2班又转来了一个yuhaoran,s[2]["yuhaoran"]++
现在2班一共有多少个yuhaoran? cout<<s[2]["yuhaoran"]<<endl;
#include<iostream>
#include<map>
#include<string>
using namespace std;
int main(void)
{map<int, map<string, int> > info;int n;cin >> n;for (int i = 0; i < n; i++){int class_id;string name;cin >> class_id >> name;info[class_id][name]++;}for (map<int, map<string, int> >::iterator it = info.begin(); it != info.end(); it++){for (map<string, int>::iterator it1 = it->second.begin(); it1 != it->second.end(); it1++){cout << "There are " << it1->second << " people name " << it1->first << " int class " << it->first << endl;}}return 0;
}
四、锯齿矩阵
是指每行包含的元素个数不相同的矩阵
#include<iostream>
#include<vector>
using namespace std;
vector<int> mat[10005];//定义了一个vector类型的数组
int main(void)
{int n, m,x,y;cin >> n >> m;for (int i = 0; i < m; i++){cin >> x >> y;mat[x].push_back(y);}for (int i = 0; i <= n; i++){for (int j = 0; j < mat[i].size(); j++){if (j != mat[i].size() - 1){cout << mat[i][j] << " ";}else{cout << mat[i][j] << endl;}}cout << endl;}return 0;
}