常用STL容器(c++)

目录

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

写不出bug的小李

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值