STL–powerful weapons
C++ STL简介:
STL是Standard Template Library的简称,中文名标准模板库,惠普实验室开发的一系列软件的统称。它是由Alexander Stepanov、Meng Lee和David R Musser在惠普实验室工作时所开发出来的。
在C++标准中,STL被组织为下面的17个头文件:<algorithm>、<deque>、<functional>、<iterator>、<array>、<vector>、<list>、<forward_list>、<map>、<unordered_map>、<memory>、<numeric>、<queue>、<set>、<unordered_set>、<stack>和<utility>。
STL内部成员介绍
NO.1:priority_queue(优先队列)
主要作用:
将元素入队,构造一个完全二叉树,可以规定为大根堆或是小根堆,自行定义,之后就不用自己每次再找o(N)的最大数了,有了树后最大是O(logN)的次数!!
内在函数的区别:
#include <bits/stdc++.h>
using namespace std;
const int N = 300000;
struct Heap {
int heap[N + 10];
int size;
void init() {
size = 1;
}
void push (int x) {
int i = size++;
while (i > 1) {
int p = (i >> 1);
if (heap[p] > x) {
break;
}
heap[i] = heap[p];
i = p;
}
heap[i] = x;
}
int pop() {
int ret = heap[1];
int x = heap[--size];
int i = 1;
while ((i << 1) < size) {
int lson = (i << 1);
int rson = (i << 1 | 1);
if (rson < size && heap[rson] > heap[lson]) lson = rson;
if (heap[lson] < x) {
break;
}
heap[i] = heap[lson];
i = lson;
}
heap[i] = x;
return ret;
}
bool empty() {
return size == 0;
}
};
int a[N];
int main () {
srand(time(NULL));
Heap my_heap;
my_heap.init();
for (int i = 0; i < N; i++) {
a[i] = rand()*rand();
}
//start here
clock_t mystart = clock();
for (int i = 0; i < N; i++) {
my_heap.push(a[i]);
}
while(!my_heap.empty()) {
my_heap.pop();
}
clock_t myend = clock();
//end here
priority_queue<int> heap;
clock_t start = clock();
for (int i = 0; i < N; i++) {
heap.push(a[i]);
}
while(!heap.empty()) {
// cout << heap.top() << endl;
heap.pop();
}
clock_t end = clock();
cout << "Running time of xjoi machine is:" << static_cast<double> (myend-mystart)/CLOCKS_PER_SEC*1000 << "ms" << endl;
cout << "Running time stl is:" << static_cast<double> (end-start)/CLOCKS_PER_SEC*1000 << "ms" << endl;
return 0;
}
定义:
1.默认(即为大根堆哦!)
2.如果是小根堆:
priority_queue<int, vector<int>, greater<int> >name;
3.如果是自定义的堆,必须自己重载operate
(1.)
#include <iostream>
#include <queue>
using namespace std;
struct Node{
int x, y;
Node( int a= 0, int b= 0 ):
x(a), y(b) {}
};
bool operator<( Node a, Node b ){
if( a.x== b.x ) return a.y> b.y;
return a.x> b.x;
}
int main(){
priority_queue<Node> q;
for( int i= 0; i< 10; ++i )
q.push( Node( rand(), rand() ) );
while( !q.empty() ){
cout << q.top().x << ' ' << q.top().y << endl;
q.pop();
}
getchar();
return 0;
}
(2).
struct Node{
int x, y;
Node( int a= 0, int b= 0 ):
x(a), y(b) {}
friend operator<( Node a, Node b ){
if( a.x== b.x ) return a.y> b.y;
return a.x> b.x;
}
};
(3).
#include <iostream>
#include <queue>
using namespace std;
struct Node{
int x, y;
Node( int a= 0, int b= 0 ):
x(a), y(b) {}
};
struct cmp{
bool operator() ( Node a, Node b ){
if( a.x== b.x ) return a.y> b.y;
return a.x> b.x; }
};
int main(){
priority_queue<Node, vector<Node>, cmp> q;
for( int i= 0; i< 10; ++i )
q.push( Node( rand(), rand() ) );
while( !q.empty() ){
cout << q.top().x << ' ' << q.top().y << endl;
q.pop();
}
getchar();
return 0;
}
成员函数(不全):
1.push() //加入堆之中
2.top() //return 最顶端的根
3.pop()//删除顶端函数
NO.2:map
主要作用:
map是一类关联式容器对于迭代器来说可以修改实值,而不能修改key。主要就是一个可以开很大的数组
使用方法:
1.定义:
#include<map>
typedef map<int,int> Edge;
Edge a;
2.插入数据:
已经对于[]进行了重载,不在是数字的数组下标,还可以是字符串!厉害了,我的哥!
a[1]=10;
a[2]=11;
注:
插入1时,先在a中查找主键为1的项,没发现,然后将一个新的对象插入a,键是1,值是一个空int,插入完成后,将int赋为"10";
该方法会将每个值都赋为缺省值,然后再赋为显示的值,如果元素是类对象,则开销比较大。我们可以用以下方法来避免开销:
a.insert(map<int, int> :: value_type(1, 10));
3.删除数据
iterator erase(iterator it); //通过一个条目对象删除
iterator erase(iterator first, iterator last); //删除一个范围
size_type erase(const Key& key); //通过关键字删除
NO.3:二分函数的用法:
STL algorithm 函数库中 利用二分思想的函数基本上有那么4个:
upper_bound()
lower_bound()
equal_range()
binary_search()
1.lower_bound()
用法: 比如在a[1~n]之中找到 m
就是 int loc = lower_bound(a+1,a+1+n,m)-a;
=ans >ans
在容器中找一个键,如果有这个键值,就返回其地址
如果没有该键,就返回一个比其大的键值的迭代器(迭代器可以理解为一个地址,键值的地址)
如果都比这个键值要来的小,就返回尾指针,即为end
2.upper_bound
>ans =ans
和lowerbound相反,先找一个键值比参数大的数,在返回,不然就是返回键值相同的迭代器,如果都一样大的话就是返回一个end!
3.equal_range()
略…
4.binary_search()
bool型的函数—就是利用二分查找!
十分好用啊!
NO.4:vector
主要作用:
就是不定长数组
内部成员介绍:
vector<int> s;
s.at() //返回s的指定位置
s.back() //返回s的末尾元素
s.end() //返回s的末尾元素的迭代器(指针) ,实际为末尾元素的后面一位
s.empty() // 判断s的元素是否为空 ,没有就返回 true 不然就返回 false
s.erase() // 删除 s 中的元素
s.front() // 返回第一个元素
s.pop_back() // 删除末尾的一个元素
s.push_back() //向末尾加入一个数据
s.size() // 返回元素的个数
s.swap() // 交换 2 个vector
NO.5:stack
主要作用:
就是一个系统自带的栈啊!
栈是什么?
先入后出的就是栈了!就是与队列相反!
内部成员的区别:
定义:
#include <stack>
stack<int> my_stack;//存放着类型为int的栈!
1.my_stack.empty()//栈为空时就是true
2.my_stack.pop()//删除栈的顶元素
3.my_stack.push()//加入一个顶元素
4.my_stack.size()//返回栈的元素个数
5.my_stack.top()//栈的顶元素!!
一般来说是这样的:
while(!my_stack.empty)
{
cout<<my_stack.top();
my.stack.pop();
}
NO.6: 全排列函数:
十分的暴力啊….无语(强大的STl)
#include <stdio.h>
#include <algorithm>
using namespace std;
int main(){
int n;
while(scanf("%d",&n)&&n){
int a[1000];
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
}
sort(a,a+n);//可以自行测试一下删除后的结果
do{
for(int i=0;i<n;i++)
printf("%d ",a[i]);
printf("\n");
}while(next_permutation(a,a+n));
}
return 0;
}