STL——STL小结

·这个就是个偷懒的玩意儿

一、介绍:

·STL:标准模板库.Standard Template Library

·STL中有神马???:

pair
vector, stack, queue, deque
priority_queue
map, set
algorithm
cmp与运算符重载


 二、Pair

·#include <utility>
·里面有两个元素first和second.
可以比较大小,先比first再比second.

#include <cstdio>
#include <utility>

using namespace std;

int main() {
	pair <int, int> _pair1, _pair2;
	_pair1.first = 1, _pair1.second = 2;
	_pair2.first = 2, _pair2.second = 2;
	printf("%d\n", _pair1 < _pair2);
	return 0;
}

三、vector

·#include <vector>
·动态数组.
·vector在STL内的实现方式.
vector是STL其他数据结构的基础.
·常用接口:
push_back();
[];
empty(), size(), clear().

#include <cstdio>
#include <vector>

using namespace std;

int main() {
	vector <int> vec;
	
	vec.push_back(1);
	vec.push_back(2);
	vec.push_back(3);
	printf("%d %d %d\n", vec[0], vec[1], vec[2]);
	printf("size = %d\n", vec.size());
	
	vec.clear();
	printf("size = %d\n", vec.size());
	return 0;
}

·STL数据结构的begin()和end()
大部分STL数据结构的内部实现都有vector.
因为是不定长数组,所以STL都有begin()和end()代表存储的地址.
begin()表示某个STL数据结构的开始地址.
end()表示某个STL的结束地址的后一位.
一般STL数据结构都有find()函数,如果STL没有找到,就会返回end().


 四、 stack

·#include <stack>
·栈.
·常用接口:
top();
push();
pop();
empty(), size();
没有clear().

#include <cstdio>
#include <stack>

using namespace std;

int main() {
	stack <int> s;
	
	while (!s.empty()) s.pop(); //clear

	s.push(1);
	s.push(2);
	s.push(3);
	printf("%d\n", s.top());
	s.pop();
	printf("%d\n", s.top());
	return 0;
}

 五、queue

·#include <queue>
·队列.
·常用接口:
front(), back();
push();
pop();
empty(), size();
没有clear().

#include <cstdio>
#include <stack>

using namespace std;

int main() {
	stack <int> s;
	
	while (!s.empty()) s.pop(); //clear

	s.push(1);
	s.push(2);
	s.push(3);
	printf("%d\n", s.top());
	s.pop();
	printf("%d\n", s.top());
	return 0;
}

 六、deque

·#include <deque>
·双端队列.
·常用接口:
front(), back();
push_back(), push_front();
pop_back(), pop_front();
empty(), size(), clear().

#include <cstdio>
#include <deque>

using namespace std;

int main() {
	deque <int> d;
	
	d.clear();
	
	d.push_back(1);
	d.push_back(2);
	d.push_back(3);
	printf("%d\n", d.front());
	printf("%d\n", d.back());
	
	d.pop_back();
	printf("%d\n", d.front());
	printf("%d\n", d.back());
	
	d.push_front(100);
	d.push_front(200);
	d.push_front(300);
	printf("%d\n", d.front());
	printf("%d\n", d.back());
	
	d.pop_front();
	printf("%d\n", d.front());
	printf("%d\n", d.back());
	
	return 0;
}

七、bitset

·#include <bitset>
·二进制数组,每个位置只能赋值0或者1.
·常用接口:
[].
bitset用cout输出比较好.

#include <cstdio>
#include <iostream>
#include <bitset>

using namespace std;

int main() {
	bitset <5> b;
	
	b[1] = 1;
	b[2] = 1;
	
	cout << b << endl;
	
	return 0;
}

八、priority_queue

·#include <queue>
·优先队列(堆)  这个比较有用.
·常用接口:
top();
push();
pop();
empty(), size();
没有clear().

#include <cstdio>
#include <queue>

using namespace std;

int main() {
	priority_queue <int> q; //澶ф牴鍫?
	//priority_queue <int, vector<int>, greater<int> > q; //灏忔牴鍫?
	
	while (!q.empty()) q.pop(); //clear
	
	q.push(1);
	printf("%d\n", q.top());
	q.push(2);
	printf("%d\n", q.top());
	q.push(3);
	printf("%d\n", q.top());
	q.push(4);
	printf("%d\n", q.top());
	
	q.pop();
	printf("%d\n", q.top());
	
	return 0;
}

九、set

·#include <set>
·集合.
·常用接口:
insert(), erase();
find();
empty(), size(), clear().

#include <cstdio>
#include <set>

using namespace std;

int main() {
	set <int> s;
	
	s.clear();
	
	s.insert(1);
	s.insert(100);
	printf("%d\n", s.find(10) == s.end());

	s.insert(10);
	printf("%d\n", s.find(10) == s.end());
	
	s.erase(10);
	printf("%d\n", s.find(10) == s.end());
	
	return 0;
}

十、multiset  

·#include <set>
·可以重复的集合.
·常用接口:
insert(), erase();
find(), count();
empty(), size(), clear().
注意,这里的erase()会把所有相同的东西全部删掉.

#include <cstdio>
#include <set>

using namespace std;

int main() {
	multiset <int> m;
	
	m.clear();
	
	m.insert(1);
	m.insert(100);
	printf("%d\n", m.find(10) == m.end());

	m.insert(10);
	printf("%d\n", m.find(10) == m.end());
	
	m.insert(10);
	printf("%d\n", m.count(10));
	
	m.erase(10);
	printf("%d\n", m.find(10) == m.end());
	printf("%d\n", m.count(10));
	
	
	return 0;
} 

 十一、map

·#include <map>
·映射.
·map里面的元素都是pair类型的.
·常用接口:
insert(), erase();
find();
[];
empty(), size(), clear().

#include <cstdio>
#include <map>

using namespace std;

int main() {
	map <int, int> m;
	
	m.clear();
	
	m.insert(make_pair(1, 1));
	m[2] = 2;
	m[3] = 3;
	
	printf("%d %d\n", m.find(1) == m.end(), m.find(4) == m.end());
	printf("%d %d\n", m[1], m[2]);
	
	m.erase(1);
	printf("%d\n", m.find(1) == m.end());
	return 0;
}

十二、hash_map

·不想自己写hash,不建议使用c++的hash_map.
·hash_map并不是标准STL,所以在cplusplus.com上面没有.
·在linux上hash_map是__gnu_cxx里面的,而unordered_map是c++11里面的数据结构,这两个都没法在考试中调试.
100%不建议使用,真的不想/会手写hash,请用map来替代.


十三、iterator

·每个STL数据结构都有对应的iterator,中文叫迭代器.
·例如set<int>的迭代器就是set<int>::iterator,迭代器的用处是可以访问数据结构内部的元素.
例如set,multiset和map都是内部排好序的,我们可以通过迭代器从小到大访问.
·迭代器本身是一个指针,访问内部元素要用*或者->.

#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <set>

using namespace std;

int main() {
	srand(time(0));
	set<int> s;
	for (int i = 1; i <= 10; ++i) {
		int x = rand() % 100000;
		if (s.find(x) == s.end()) s.insert(x);
	}
	
	for (set<int>::iterator iter = s.begin(); iter != s.end(); iter++) {
		printf("%d ", *iter);
	}
	puts("");
	
	set<int>::iterator lower_iter = s.lower_bound(10000);
	set<int>::iterator upper_iter = s.upper_bound(10000);
	
	printf("%d %d\n", *lower_iter, *upper_iter);
	
	return 0;
}

十四、lower_bound(),upper_bound()

·对于一个set,可以用lower_bound和upper_bound来进行二分查询:
·s.lower_bound(x)返回一个iterator,指向大于等于x的最小的元素,如果没有这样的元素,则返回随机值.
·s.upper_bound(x)和s.lower_bound(x)是一个意思,唯一差别是没有等于.
·upper_bound不是返回小于!


十五、Caution

·注意:STL的数据结构比较金贵,所以要时刻考虑是不是为空的情况,否则很容易RE.
·RE典型例子:
vector通过下标访问越界.
stack为空的时候访问top().
·地址越界不一定会RE,但是还是会影响程序的正常运行.


十六、algorithm

·STL里还有一个算法库,有几个比较好用的算法.
sort() 序列排序;
reverse() 序列翻转;
random_shuffle() 序列打乱;
next_permutation() 生成下一个排列;
min(), max(), swap() 取最大最小值,两个元素交换.

#include <cstdio>
#include <algorithm>

using namespace std;

int main() {
	int x = 1, y = 2;
	
	printf("%d\n", min(x, y));
	printf("%d\n", max(x, y));
	
	swap(x, y);
	printf("%d %d\n", x, y);
	
	int a[10];
	a[1] = 5;
	a[2] = 6;
	a[3] = 3;
	a[4] = 4;
	
	sort(a + 1, a + 4 + 1); //end should be a+4 + 1!!!
	printf("%d %d %d %d\n", a[1], a[2], a[3], a[4]);
	
	reverse(a + 1, a + 4 + 1);
	printf("%d %d %d %d\n", a[1], a[2], a[3], a[4]);
	
	random_shuffle(a + 1, a + 4 + 1);
	printf("%d %d %d %d\n", a[1], a[2], a[3], a[4]);
	
	puts("");
	a[1] = 1, a[2] = 2, a[3] = 3;
	for (int i = 1; i <= 6; ++i) {
		printf("%d %d %d\n", a[1], a[2], a[3]);
		next_permutation(a + 1, a + 3 + 1);
	}
	return 0;
}

十七、sort

·algorithm中比较重要的函数就是sort().
·用处是对一个序列进行从小到大的排序.
sort()并不是单纯的快速排序,但是时间复杂度也是O(nlogn)的.
sort()可以对数组或者vector排序,但是不能对其他STL数据结构排序.
sort()的第一个参数是数组的开始,第二个参数是数组结尾的后一个位置.
sort()还有第三个参数,cmp.


十八、reverse

·这个比较简单,就是把一个数组进行翻转.
·参数和sort一样,第一个参数是数组的开始,第二个参数是数组结尾的后一个位置.


十九、random_shuffle

·这个也比较简单,就是把一个数组的内容打乱.
·参数和sort一样,第一个参数是数组的开始,第二个参数是数组结尾的后一个位置.


二十、next_permutation

·这个也比较简单,就是生成当前排列的下一个排列(字典序意义).
·参数和sort一样,第一个参数是数组的开始,第二个参数是数组结尾的后一个位置.
·当然也有一个函数prev_permutation(),用于生成当前排列的上一个排列(字典序意义)  


·注:

·STL里的接口忘了怎么办?
cplusplus.com可以查询.

·STL里的简单数据(栈,队列)结构建议手写,因为不好检查.
·map,set比较难实现,建议用STL.

·STL里的算法因为封装常数比较大,可能会被卡常数,例如vector.

猜你喜欢

转载自www.cnblogs.com/konglingyi/p/11391131.html
STL