C++STL总结

yls的总结:  

 

 

1.vector

#include <vector> 头文件

vector<int> a; 相当于一个长度动态变化的int数组

vector<int> b[233]; 相当于第一维长233,第二位长度动态变化的int数组

struct rec{…};

vector<rec> c; 自定义的结构体类型也可以保存在vector中

size/empty

size函数返回vector的实际长度(包含的元素个数),empty函数返回一个bool类型,表明vector是否为空。二者的时间复杂度都是O(1)。

所有的STL容器都支持这两个方法,含义也相同,之后我们就不再重复给出。

clear

clear函数把vector清空。

front/back

front函数返回vector的第一个元素,等价于*a.begin() 和 a[0]。

back函数返回vector的最后一个元素,等价于*==a.end() 和 a[a.size() – 1]。

push_back() 和 pop_back()

a.push_back(x) 把元素x插入到vector a的尾部。

b.pop_back() 删除vector a的最后一个元素。

迭代器

迭代器就像STL容器的“指针”,可以用星号“*”操作符解除引用。

一个保存int的vector的迭代器声明方法为:

vector<int>::iterator it;

vector的迭代器是“随机访问迭代器”,可以把vector的迭代器与一个整数相加减,其行为和指针的移动类似。可以把vector的两个迭代器相减,其结果也和指针相减类似,得到两个迭代器对应下标之间的距离。

begin/end

begin函数返回指向vector中第一个元素的迭代器。例如a是一个非空的vector,则*a.begin()与a[0]的作用相同。

所有的容器都可以视作一个“前闭后开”的结构,end函数返回vector的尾部,即第n个元素再往后的“边界”。*a.end()与a[n]都是越界访问,其中n=a.size()。

some code:

​
#include <iostream>
#include <vector>
//push_back/pop_back/clear/empty/size/front/back
using namespace std;

struct res
{
	int x, y;
};
int main()
{
	//存一维数组,a[]
	vector<int> a;
	for (int i = 0; i < 5; i ++)
	{
	    a.push_back(i);
	    cout << a[i] << ' ';
	}
	cout << endl;
	//empty()返回的是一个bool值
	//如果数组为空,返回true,即1;如果数组不为空,则返回false,即0
	int re = a.empty();
	cout << re << endl;
	
	//pop_back()删除数组中的最后一位数
	a.pop_back();	
	for (int i = 0; i < a.size(); i ++)
	{
		cout << a[i] << ' ';
	}
    cout << endl;
    //clear把数组清空
	a.clear();
	cout << a.empty() << endl;
    //用vector存结构体
    //总操作就是将q这个结构体存入vector p中
	vector<res> p;
    res q;
    int x, y;
	cin >> x >> y;
	q.x = x;
	q.y = y;
	p.push_back(q);
	//迭代器的声明:vector<int>::iterator
	//迭代器与指针类似
	for (vector<res>::iterator i = p.begin(); i != p.end(); i ++)//迭代器遍历,auto->vector<int>::iterator
	{
		cout << (*i).x << ' ' << (*i).y << endl;
	}
	for (auto j = p.begin(); j < p.end(); j ++)
	{
		cout << (*j).x << ' ' << (*j).y << endl;
	}
	cout << endl;
	//用vector存二维数组,b[5][],一维固定,二维动态变化
	vector<int> b[5];
	int cnt = 1;
	for (int i = 0; i < 5; i ++)
	{
		for (int j =0; j < 5; j ++)
		{
			b[i].push_back(cnt);
			cout << b[i][j] <<' ';
			cnt ++;
		}
	}
	cout << endl;
	//用vector来存字符数组,c[]
	vector<char> c;
	for (int i = 'a', j = 0; i <= 'z'; i ++, j ++)
	{
		c.push_back(i);
		cout << c[j] << ' ';
	}
	cout << endl;
	cout << "迭代器" <<endl;
	vector<int> d;
	for (int i = 0; i < 5; i ++)
	{
		d.push_back(i);
	}
	d.pop_back();
	d.push_back(10);
	vector<int>::iterator it = d.begin();
	cout <<  *(it + 2) << endl; //与下面一种不相同
	cout << *it + 2 << endl;//上面一种访问的是d[2],下面一种是a[0] + 2;
	cout << *it + d.size() - 1 << endl;//访问最后一位数
	cout << *(d.end() - 1 ) << endl;//访问最后一位数
	cout << *d.end()<< endl;//访问越界,d.end()表示的是数组最后一位的下一个位置
 
	while (it != d.end())
	{
		cout << *it << ' ';
		it ++;
	} 
	cout << endl;
	//front/back
	cout << d.front() << endl;//d[0]
	cout << d.back() + 3 << endl;
	cout << d.back() << endl;//d[d.size() - 1]

}

​

 2.queue

#include <queue>

头文件queue主要包括循环队列queue和优先队列priority_queue两个容器。

声明

queue<int> q;

struct rec{…}; queue<rec> q; //结构体rec中必须定义小于号

priority_queue<int> q; // 大根堆

priority_queue<int, vector<int>, greater<int> q; // 小根堆

priority_queue<pair<int, int>>q;

循环队列 queue

push 从队尾插入

pop 从队头弹出

front 返回队头元素

back 返回队尾元素

优先队列 priority_queue

priority_queue<int> q; // 大根堆

priority_queue<int, vector<int>, greater<int> q; // 小根堆

push 把元素插入堆

pop 删除堆顶元素

top 查询堆顶元素(最大值)

some code:

​
#include <iostream>
#include <queue>

using namespace std;

int main()
{
	//队列queue
	//push/pop/front/back/empty
	//push
	queue<int> a;
    for (int i = 0; i < 5; i ++)
    {
		a.push(i);//从队尾插入
	}
	//front/back
	cout << a.front() << endl;//返回队头元素
	cout << a.back() << endl;//返回队尾元素
	a.pop();//把队头拿掉
	cout << a.front() << endl;
	a.pop();
	cout << a.front() << endl;
	
	cout << "清空一个数组:"<<endl;
	queue<int> b;
	for (int i = 0; i < 5 ; i ++)
	{
		b.push(i);
	} 
	for (int i = 0; i < 5; i ++)
	{
		b.pop();
	}
	//empty
	cout << b.empty() << endl;
	//队列是无序的
	queue<int> c;
	c.push(9);
	c.push(1);
	c.push(2);
	cout << c.front() << endl;
	
	//队列里面装结构体
	cout << "队列里面装结构体:" << endl;
	//定义一个结构体
	struct res
	{
		int x, y;
		bool operator < (const res& t) const//结构体内必须定义小于号
		{
			return x < t.x;
		}
	};
	queue<res> d;//定义一个结构体的队列
	res p;
	p.x = 1;
	p.y = 2;
	d.push(p);//将p这个结构体插到d这个队列中去
	res q;
	q.x = 4;
	q.y = 3;
	d.push(q);//将q这个结构体插入到d这个队列中去
	
	cout << d.front().x << ' ' << d.front().y << endl;//输出队头
	cout << d.back().x << ' ' << d.back().y << endl;//输出队尾
	d.pop();//将队头删掉
	cout << d.front().x << ' ' << d.front().y << endl;
	cout << endl;
	
	
	//优先队列priority_queue(大根堆)
	priority_queue<int> m;//大根堆,堆顶为大根
	//push/pop/top
	//push
	m.push(5);
	m.push(1);
	m.push(6);
	m.push(2);
	//top
	cout << m.top() << endl;//输出最大值
	//pop
    m.pop();//删除堆顶
    cout << m.top() << endl;
    //大根堆里装结构体
    struct ans
    {
		int v, w;
		bool operator < (const ans& t) const //大根堆定义小于号
		{
			return v < t.v;
		}
	};
	priority_queue<ans> n;
	ans a1;
	a1.v = 2;
	a1.w = 1;
	ans a2;
	a2.v = 2;
	a2.w = 0;
	n.push(a1);
	n.push(a2);
	//先比较v,谁大谁堆顶
	//v相同比较w,谁大谁堆顶
	cout << n.top().v << ' ' << n.top().w << endl;
	n.pop();//删除堆顶
	cout << n.top().v << ' ' << n.top().w << endl;
	cout << endl;
	
	
	//优先队列priority_queue<int,vector<int>,greater<int>>(小根堆)
	//push/top/pop
	priority_queue<int, vector<int>, greater<int>> s;
	//push
	s.push(5);
	s.push(1);
	//top
	cout << s.top() << endl;
	//小根堆里装结构体
	struct sum
	{
		int t1, t2;
		bool operator > (const sum& t) const //小根堆定义大于号
		{
			return t1 > t.t1;
		}
	};
	priority_queue<sum, vector<sum>, greater<sum>> k;
	sum s1;
	s1.t1 = 1;
	s1.t2 = 5;
	sum s2;
	s2.t1 = 0;
	s2.t2 = 9;
	k.push(s1);
	k.push(s2);
	cout << k.top().t1 << ' ' << k.top().t2 << endl;
	//pop
	k.pop();
	cout << k.top().t1 << ' ' << k.top().t2 << endl;	
}

​

3.stack 

头文件stack包含栈。声明和前面的容器类似。

push 向栈顶插入

pop 弹出栈顶元素

some code:

​
#include <iostream>
#include <stack>
//push/pop/top/empty/size
using namespace std;

int main()
{
	stack<int> a;
	//先进后出
	//push向栈顶插入
	a.push(1);
	a.push(3);
	a.push(2);
	cout << a.top() << endl;
    a.pop();//弹出栈顶元素
    cout << a.top() << endl;
    cout << a.empty() << endl;
    cout << a.size() << endl;
}

​

4.deque

双端队列deque是一个支持在两端高效插入或删除元素的连续线性存储空间。它就像是vector和queue的结合。与vector相比,deque在头部增删元素仅需要O(1)的时间;与queue相比,deque像数组一样支持随机访问。

[] 随机访问

begin/end,返回deque的头/尾迭代器

front/back 队头/队尾元素

push_back 从队尾入队

push_front 从队头入队

pop_back 从队尾出队

pop_front 从队头出队

clear 清空队列

some code: 

​
#include <iostream>
#include <deque>

using namespace std;

int main()
{
	deque<int> a;
    for (int i = 0; i < 5; i ++)
    {
		a.push_back(i);
	}
	cout << a.front() << endl;
	cout << a.back() << endl;
	deque<int> b;
	for (int i = 0; i < 5; i ++)
	{
		b.push_front(i);
	}
	cout << a.front() << endl;
	cout << a.back() << endl;
}

​

5.set 不含重复元素的哈希表

头文件set主要包括set和multiset两个容器,分别是“有序集合”和“有序多重集合”,即前者的元素不能重复,而后者可以包含若干个相等的元素。set和multiset的内部实现是一棵红黑树,它们支持的函数基本相同。

声明

set<int> s;

struct rec{…}; set<rec> s; // 结构体rec中必须定义小于号

multiset<double> s;

size/empty/clear

与vector类似

insert

s.insert(x)把一个元素x插入到集合s中,时间复杂度为O(logn)。

在set中,若元素已存在,则不会重复插入该元素,对集合的状态无影响。

find

s.find(x) 在集合s中查找等于x的元素,并返回指向该元素的迭代器。若不存在,则返回s.end()。时间复杂度为O(logn)。

lower_bound/upper_bound

这两个函数的用法与find类似,但查找的条件略有不同,时间复杂度为 O(logn)。

s.lower_bound(x) 查找大于等于x的元素中最小的一个,并返回指向该元素的迭代器。

s.upper_bound(x) 查找大于x的元素中最小的一个,并返回指向该元素的迭代器。

erase

设it是一个迭代器,s.erase(it) 从s中删除迭代器it指向的元素,时间复杂度为O(logn)

设x是一个元素,s.erase(x) 从s中删除所有等于x的元素,时间复杂度为O(k+logn),其中k是被删除的元素个数。

count

s.count(x) 返回集合s中等于x的元素个数,时间复杂度为 O(k +logn),其中k为元素x的个数。

迭代器

set和multiset的迭代器称为“双向访问迭代器”,不支持“随机访问”,支持星号(*)解除引用,仅支持”++”和--“两个与算术相关的操作。

设it是一个迭代器,例如set<int>::iterator it;

若把it++,则it会指向“下一个”元素。这里的“下一个”元素是指在元素从小到大排序的结果中,排在it下一名的元素。同理,若把it--,则it将会指向排在“上一个”的元素。

begin/end

返回集合的首、尾迭代器,时间复杂度均为O(1)。

s.begin() 是指向集合中最小元素的迭代器。

s.end() 是指向集合中最大元素的下一个位置的迭代器。换言之,就像vector一样,是一个“前闭后开”的形式。因此--s.end()是指向集合中最大元素的迭代器。

some code:

​
#include <iostream>
#include <set>
//size/empty/clear
//insert
//find
//lower_bound //查找大于等于x的最小元素
//upper_bound //查找大于x的最小元素
//erase//假设it为一个迭代器,erase(it),删除it迭代器所指元素
//count//返回的是x在集合中出现的个数
using namespace std;

int main()
{
	//set(没有重复元素且有序)
	set<int> a;
	//insert
	a.insert(1);
	a.insert(3);
	a.insert(1);
	a.insert(2);
	for (auto i = a.begin(); i != a.end(); i ++)
	{
		cout << *i << ' ';
	}
	//size
	cout << endl;
	cout << a.size() << endl;
	//lower_bound/upper_bound
	cout << *a.lower_bound(2) << endl;
	cout << *a.upper_bound(2) << endl;
	cout << a.count(1) << endl;
	cout << "*" << endl;
	a.erase(a.begin());
	cout << *a.begin() << endl;
	//利用find查找元素
	//找到元素则返回的是该元素的迭代器
	//没有找到,则a.find(n)==a.end(),返回的是a.end()
	int n;
	cin >> n;
	if (a.find(n) != a.end())
	{
		cout << *a.find(n) << endl;
	}
	else
	{
		cout << "not find" << endl;
	}
	cout << endl;
	struct res
	{
		int x, y;
		bool operator < (const res& t) const
		{
            return x < t.x;
		}
	};
	set<res> b;
	res p;
	p.x = 1;
	p.y = 2;
	res q;
	q.x = 1;
	q.y = 2;
	res s;
	s.x = 3;
	s.y = 4;
	b.insert(s);
	b.insert(p);
	b.insert(q);
	//迭代器访问结构体时候,*去掉,加->
    for (set<res>::iterator i = b.begin(); i != b.end(); i ++)
    {
		cout << i->x << ' ' << i->y << endl;
	}
	cout << endl;
	for (auto i = b.begin(); i != b.end(); i ++)
	{
		cout << i->x << ' ' << i->y << endl;
	}
	cout << endl;
	//multiset(有重复元素且有序)
	multiset<int> c;
	c.insert(1);
	c.insert(1);
	c.insert(2);
	c.insert(3);
	for (auto i = c.begin(); i != c.end(); i ++)
	{
		cout << *i << ' ';
	}
	cout << endl;
	cout << c.count(1) << endl;
	
}

​

6.map//有序无重复元素

map容器是一个键值对key-value的映射,其内部实现是一棵以key为关键码的红黑树。Map的key和value可以是任意类型,其中key必须定义小于号运算符。

声明

map<key_type, value_type> name;

例如:

map<long, long, bool> vis;

map<string, int> hash;

map<pair<int, int>, vector<int>> test;

size/empty/clear/begin/end均与set类似。

Insert/erase

与set类似,但其参数均是pair<key_type, value_type>。

find

h.find(x) 在变量名为h的map中查找key为x的二元组。

[]操作符

h[key] 返回key映射的value的引用,时间复杂度为O(logn)。

[]操作符是map最吸引人的地方。我们可以很方便地通过h[key]来得到key对应的value,还可以对h[key]进行赋值操作,改变key对应的value。

some code:

#include <iostream>
#include <map>
#include <vector>

using namespace std;

int main()
{
	map<int, int> a;
	a.insert({1, 2});
	cout << a[1] << endl;
	map<string, vector<int>> b;
	b["xy"] = vector<int>({1, 2, 3, 4});
	for (auto i = b["xy"].begin(); i != b["xy"].end(); i ++)
	{
		cout << *i << ' '; 
	}
	cout << endl;
	cout << endl;
	cout << b["xy"][2] << endl;
	cout << endl;
	cout << (b.find("xy") == b.end()) << endl;
	cout << *b["xy"].begin() << endl;
	b["xy"].erase(b["xy"].begin());
	cout << *b["xy"].begin() << endl;
	
}

7.unordered_map/unordered_set 无序哈希表

some code:

#include <iostream>
#include <unordered_map>

using namespace std;

int main()
{
	unordered_map<int, int> a;
	for (int i = 0; i < 5; i ++)
    {
		 a.insert({i, i});
	}
	for (int i = 0; i < 5; i ++)
	{
		cout << a[i] << ' ';
	}
	cout << endl;
}
#include <iostream>
#include <unordered_set>
//先入后出
using namespace std;

int main()
{
	//unordered_set(存储不重复元素且无序)
	unordered_set<int> a;
	a.insert(2);
	a.insert(1);
	a.insert(3);
    for (auto i = a.begin(); i != a.end(); i ++)
    {
		cout << *i << ' ';
	}
	cout << endl;
	//unordered_multiset(可存储重复元素且无序)
	unordered_multiset<int> b;
	b.insert(1);
	b.insert(1);
	b.insert(3);
	b.insert(2);
	for (auto i = b.begin(); i != b.end(); i ++)
	{
		cout << *i << ' ';
	}
	cout << endl;
}

 8.bitset

some code:

#include <iostream>
#include <bitset>
//set/reset/count
using namespace std;

int main()
{
	bitset<1000> a;
	a[0] = 1;
	a[1] = 0;
	a[2] = 1;
	cout << a[0] << endl;
	a.set(1);//把a[1] 变成 1
	cout << a[1] << endl;
	a.reset(0);//把a[0] 变成 0
	cout << a[0] << endl;
	cout << a.count() << endl;
}

注:本篇文章参考内容来自acwing!!!


所有笔记总结目录-CSDN博客

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值