C++ STL

本文通过实战演示了C++标准模板库(STL)中关键数据结构的应用,包括排序(sort)、查找(lower_bound)、Vector容器、Set集合、Map映射、Stack栈、Queue队列及优先队列(priority_queue)的使用方法。

刷完一波水题决定向高级技术进军,但是智商捉急,看高级专题比较费劲,还是要把基础的东西夯实。因此决定先看下基础的STL和数据结构基础,顺便刷一波题目。

排序

sort(a,a+n,compare) a是数组首地址,n是数组元素个数,compare是排序比较函数。本函数包含在头文件algorithm当中,默认对于一个数组或者vector进行排序,compare函数可以不写,默认就是升序排序。实现compare函数如下:

bool compare(int a,int b){
    return a<b; //升序排序
    //return a>b; //将序排序
}

lower_bound(a,a+n,x) a是数组首地址,n是元素个数,x是要查找的数,函数返回大于等于x的元素的地址,由于是地址,需要减去首地址才能作为下标取到这个x。
demo代码如下:

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
bool compare(int a,int b){
    return a<b;
}
int main()
{
    const int n=7;
    int number[n]={3,4,2,1,76,8,1};
    sort(number,number+n,compare);
    for(int i=0;i<n;i++)
        printf("%d ",number[i]);
    printf("\n");
    printf("%x",lower_bound(number,number+n,4));
    //这里打印的是地址
    return 0;
}

Vector

容器类,高级数组,基本操作的DEMO如下:

#include <iostream>
#include <cstdio>df
#include <algorithm>
#include <vector>
using namespace std;
int main()
{
    const int n=10;
    vector<int> number;
    vector<int>::iterator it; //迭代器使用的时候再赋值
    //添加数并显示
    for(int i=n-1;i>=0;i--){
        number.push_back(i);
    }
    for(it=number.begin();it!=number.end();it++) //实际上只是更改了number容器的尾指针
        printf("%d ",*it);
    //删除尾巴
    number.pop_back();
    number.pop_back();
    printf("\n");
    //没有尾巴的输出
    for(int i=0;i<number.size();i++) //实际上只是更改了number容器的尾指针,
        printf("%d ",number[i]);
    printf("\n%d",number[n-2]);  //我们发现vector里面的值并没有删除,只是看不到而已
    printf("\n%d",number.back()); //back可以让我们看到真正的尾巴
    return 0;
}

Set

Set实现了平衡二叉搜索树,类似于我们高中所学的集合,里面的内容是不能重复的。另外,里面的元素插入就会自动排序。DEMO代码如下:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <set>
using namespace std;
//Ctrl+L删除一行
//Set实现了平衡二叉搜索树
bool compare(int a,int b){
    return a<b;
}
int main(){
    const int n=10;
    set<int> myset;
    set<int>::iterator it;
    set<int>::reverse_iterator rit;
    //初始化set
    for(int i=0;i<10;i++){
        myset.insert(i);
    }
    myset.insert(10); //10是可以插入进去的
    myset.insert(9);  //9就插入不进去了,因为set不允许有重复元素
    myset.erase(1); //删除元素
    //正遍历和反遍历
    for(it=myset.begin();it!=myset.end();it++){
        printf("%d ",*it);
    }
    printf("\n");
    for(rit=myset.rbegin();rit!=myset.rend();rit++){ //首尾分别变成了rbegin和rend
        printf("%d ",*rit);
    }
    printf("\n%d",*myset.find(2)); //查找使用find函数
    //rt(myset.begin(),myset.end(),compare);
    return 0;
}

Map

Map是非常有用的数据结构,可以反映数据之间的关联关系。C++中的Map实现了红黑树,并且是严格按照Key的顺序排序的。DEMO代码如下:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <string>
#include <algorithm>
#include <map>
//#define LOCAL
using namespace std;\
map<string,int> m;
map<string,int>::iterator it;
pair<map<string,int>::iterator ,bool>ss; //检测插入是否成功
//map的DEMO
int main(){
    #ifdef LOCAL
    freopen("input.txt","r",stdin);
    #endif // LOCAL
    m.insert(pair<string,int>("Jan",1)); //插入顺序和声明的pair要相一致
    m.insert(pair<string,int>("Feb",1));
    m.insert(pair<string,int>("Mar",1));
    ss=m.insert(pair<string,int>("Mar",2)); //重复key的value不会被插入
    if(ss.second==true)
        cout<<"Insert Success!"<<endl;
    else
        cout<<"Insert Failed!"<<endl;
    m["Apr"]=4;
    m["Apr"]=5; //使用类似于数组方式的插入可以覆盖
    for(it=m.begin();it!=m.end();it++){
        cout<<it->first<<" "<<it->second<<endl;  
        //使用迭代器的first和second分别指向key和value
    }
    cout<<endl;
    m.erase("Jan");  //删除数据
    for(it=m.begin();it!=m.end();it++){
        cout<<it->first<<" "<<it->second<<endl;
    }
    //查找数据
    it=m.find("Feb");  //查找key,返回iterator
    cout<<"We found:"<<it->first<<" "<<it->second<<endl;
//查找key是否出现,出现返回1,否则0
    return 0;
}

Stack

栈是一个FILO的容器,Stack没有遍历方式也没有iterator,DEMO比较简单,如下:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <string>
#include <algorithm>
#include <stack>
//#define LOCAL
using namespace std;
//栈DEMO
stack<int> s;
//stack<int>::iterator it; 栈没有iterrator,也没有遍历方式
int main(){
    #ifdef LOCAL
    freopen("input.txt","r",stdin);
    #endif // LOCAL
    cout<<"Now we push some numbers:"<<endl;
    s.push(1);
    s.push(3);
    cout<<"Now the stack size is:"<<s.size()<<endl;
    while(!s.empty()){ //依次出栈
        cout<<s.top()<<endl;
        s.pop();
    }
    cout<<"Now we pop them"<<endl;
    cout<<"Now the stack size is:"<<s.size()<<endl;
    return 0;
}

Queue

队列分为普通队列(queue)和优先队列(priority_queue),队列的基本操作为入队、出队、取队首元素。两个队列取队首的函数不同,另外优先队列可以通过实现仿函数的方式定义自己的优先级。DEMO如下:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <string>
#include <algorithm>
#include <queue>
#include <list>
//#define LOCAL
using namespace std;
struct Node{
    int a;
    int b;
    Node(int t1=0,int t2=0):a(t1),b(t2){}
};
struct cmp{  //实现仿函数
    bool operator() (Node n1, Node n2){ 
    //返回true的时候n1的优先级比n2小
        return n1.a<n2.a;
    }
};
//普通队列
queue<string> q; 
//优先队列,第一个是元素类型,第二个是容器(不能用list)
//第三个是比较算子,
//默认的是greater,表示先入队的元素的优先级greater
priority_queue<int,vector<int>,less<int> > pq;
//自定义优先队列
priority_queue<Node,vector<Node>,cmp> node_q;
int main(){
    #ifdef LOCAL
    freopen("input.txt","r",stdin);
    #endif // LOCAL
    cout<<"Normal Queue DEMO:"<<endl;
    q.push("Hello") ;
    cout<<"After pushing \"Hello\":"<<endl;
    cout<<"Size of the queue:"<<q.size()<<endl;
    q.push("Next");
    cout<<"After pushing \"Next\":"<<endl;
    cout<<"Size of the queue:"<<q.size()<<endl;
    while(!q.empty()){
        cout<<q.front()<<endl;
        q.pop();
    }
    cout<<"Priority Queue DEMO:"<<endl;
    pq.push(1);
    pq.push(2);
    while(!pq.empty()){
        //出队由front变成了top,返回下一个优先级高的元素
        pq.pop();
    }
    cout<<"My own priority queue DEMO:"<<endl;
    Node node1(1,1);
    Node node2(2,2);
    node_q.push(node1);
    node_q.push(node2);
    while(!node_q.empty()){
        cout<<node_q.top().a<<endl;
        node_q.pop();
    }
    return 0;
}

P.S.关于优先队列,这篇blog可以参考下,任意门:
http://www.cnblogs.com/nirvana-phoenix/archive/2012/05/29/2524344.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值