[ACM] 常用STL

来源:互联网 发布:大张一刀流 知乎 编辑:程序博客网 时间:2024/06/09 23:13

1.  stack

[cpp] view plain copy
  1. stack<int>st;//栈st,用于存放int型数据  
  2. st.push(3);//将3入栈  
  3. st.push(2);//将2入栈  
  4. st.pop();//栈顶2出栈  
  5. int Top = st.top();//获取栈顶元素,即3  
  6. int Size = st.size();//求栈中的元素个数  
  7. bool isEmpty = st.empty(); //栈中元素是否为空,1表示空,0表示非空  
  8.   
  9. stack<T>st;  // T是存放数据的类型,可以是int, double等,也可以是自定义的结构体类型  
如:

[cpp] view plain copy
  1. struct Node  
  2. {  
  3.     int x,y;  
  4. };  
  5. stack<Node> st;  

2.  queue

[cpp] view plain copy
  1. queue<int>que;//队列que,存放int型数据  
  2. que.push(3);//将3入队列  
  3. que.push(2);//将2入队列  
  4. que.pop();//队首3出队列  
  5. int Front = que.front();//获取队首元素  
  6. int Size = que.size();//队列中元素个数  
  7. bool isEmpty = que.empty(); //是否为空  
  8.   
  9. queue<T>que;  // T是存放数据的类型,可以是int, double等,也可以是自定义的结构体类型.  

3.  priority_queue

优先队列中的元素按照一定的优先级进行排列,对于int型的元素,默认是从大到小进行排列的,队首为最大元素.

[cpp] view plain copy
  1. const int len = 5;  
  2. int a[len] = {3, 5, 9, 6, 2};  
  3. priority_queue<int> q;  
  4. for(int i = 0; i < len; ++ i)  
  5. {  
  6.     q.push(a[i]);  
  7. }  
  8. for(int i = 0; i < len; ++ i)  
  9. {  
  10.     cout<< q.top() <<endl;  
  11.     q.pop();  
  12. }  

输出的元素依次为 9 6 5 3 2

 

如果要按照从小到大排列,把priority_queue<int>q;这条语句换成

priority_queue<int,vector<int>,greater<int>>q;就可以实现。

 

另外我们可以根据需求,自己定义优先级,对’<’符号进行重载,使得队列中的元素按照一定的顺序排列,假设我们定义一个操作系统中作业的结构体,里面有两个元素,一个是作业名char name[5]; 一个是到达时间intarriveTime; 把作业对象放到优先队列里面,要求在优先队列按作业到达时间从小到大排列,即到达时间最小的作业在队首.

[cpp] view plain copy
  1. struct Job //定义作业结构体  
  2. {  
  3.     char name[5];//作业名  
  4.     int arriveTime;//到达时间  
  5.     bool operator < (const Job another)const{//如果当前作业到达时间大于另一个,则当前作业优先级小  
  6.         if(arriveTime > another.arriveTime)  
  7.             return true;  
  8.         return false;  
  9.     }  
  10. }job[3];  
  11.   
  12. int main()  
  13. {  
  14.     strcpy(job[0].name, "no1");  
  15.     strcpy(job[1].name, "no2");  
  16.     strcpy(job[2].name, "no3");  
  17.     job[0].arriveTime = 2;  
  18.     job[1].arriveTime = 1;  
  19.     job[2].arriveTime = 3;  
  20.   
  21.     priority_queue<Job> que;  
  22.     que.push(job[0]);  
  23.     que.push(job[1]);  
  24.     que.push(job[2]);  
  25.     for(int i = 0; i < 3; ++ i)  
  26.     {  
  27.         Job tempJob = que.top();  
  28.         que.pop();  
  29.         cout<< tempJob.name <<"  "<<tempJob.arriveTime<<endl;  
  30. }  
  31. return 0;  
  32. }  

输出为:

no2 1

no1 2

no3 3

实现了优先队列中的作业按照到达时间排序.


4.  vector

vector是一种容器,可以看做是动态的数组.

[cpp] view plain copy
  1. vector<int>vec;  
  2. vec.push_back(2);//尾部插入数字2,即 vec[0]=2  
  3. vec.push_back(4);//尾部插入数字4,即 vec[1]=4  
  4. int Size = vec.size();//容器中存放数字的个数  
  5. cout<< vec[1] <<endl;//访问第二个数字,即4  
  6.   
  7. for(int i = 0; i < vec.size(); ++ i)//按照下标遍历元素,此时vec[0]=2  vec[1]=4  
  8. {  
  9.     cout<< vec[i] << " ";  
  10. }  
  11. cout<<endl;  
  12.   
  13. vector<int>::iterator it;//按照迭代器遍历元素  
  14. for(it = vec.begin(); it != vec.end(); ++ it)  
  15. {  
  16.     cout<< *it <<" ";  
  17. }  
  18. cout<<endl;  
  19.   
  20. vec.insert(vec.begin() + 1, 6);//在第二个位置上插入元素6,即vec[1]=6  
  21. vec.erase(vec.begin() + 1);//删除第二个位置上的元素  
  22. vec.clear();//把容器中的元素全部清除  

另外也可以定义二维动态数组即vector<int>vec[2];也就是两个容器,用它可以很方便的保存有向图的邻接表,即vec[i]中存放的是与第i个顶点相邻的顶点(从顶点i出发),.其操作只要把上述代码中的vec改成vec[i] 就可以.


5.  set

set这种容器里面存放元素是唯一的,即不可能两个相同的数都存在set里面,set的效率比较高,起内部采用了高效的平衡检索二叉树:红黑树。插入的元素按从小到大自动排好序,第一个元素为最小值。

[cpp] view plain copy
  1. set<int>st;//容器中存放int型数据  
  2. st.insert(2);//插入元素2  
  3. st.insert(1);  
  4. st.insert(3);  
  5. st.insert(8);  
  6.   
  7. int Size = st.size();//容器中元素个数  
  8. bool isEmpty = st.empty();//元素是否为空  
  9. int has1 = st.count(1);//1这个元素是否在set中 st.count()不是1就是0  
  10. int has2 = st.count(6);//6这个元素是否在set中,has1值为1  has2值为0  
  11. st.erase(1);//在容器中删除1这个元素  
  12. bool inSet = (st.find(-2)!= st.end());//-2这个元素是否在set中  
  13. cout<<*st.lower_bound(1)<<endl;//返回set中第一个大于等于1的数  
  14. cout<<*st.upper_bound(1)<<endl;//返回set中第一个大于1的数  
  15.   
  16. set<int>:: iterator it;//遍历set容器,输出 1 2 3  
  17. for(it = st.begin(); it != st.end(); ++ it)  
  18. {  
  19.     cout<< *it <<"  ";  
  20. }  
  21. cout<<endl;  
  22.   
  23. st.clear();//清空set中的元素  

6.  map

map是一种映射关系,一对一,第一个为关键字(first),第二个为键值(second),关键字唯一,map中的元素按关键字有序. 实际应用中要考虑好关键字和键值代表的意义,灵活运用。

比如: 

[cpp] view plain copy
  1. map<string, int> mp; //关键字为string类型,键值为int 类型,我们可以用来表示某一个符  
  2. //串str出现的次数,int型键值默认为0  
  3. cout<< mp[“hello”] <<endl; //输出”hello”这个字符串出现的次数,这里原来map是空的,但  
  4. //但是我们输出了一下以后,mp的元素个数自动变成了1,但是”hello”对应的键值仍然为0  
  5.   
  6. mp.clear();//清空元素  
  7. mp.insert(make_pair("hello",1));//插入键值对,代表初始的时候"hello"出现的次数为1  
  8. mp.insert(make_pair("world",3));//插入键值对,初始的时候"world"出现的次数为3  
  9. mp.insert(make_pair("apple",1));//插入键值对,初始的时候"apple”出现的次数为1  
  10. cout<<mp.size()<<endl;//map中的元素个数,这里输出3  
  11.   
  12. map<string, int>:: iterator it;//遍历map  
  13. for(it = mp.begin(); it!= mp.end(); ++ it)  
  14. {  
  15.     cout<<it->first<<"  "<<it->second<<endl;  
  16. }  

输出如下:

apple 1

hello 1

world 3  

可以发现元素是按关键字从小到大排好序的

[cpp] view plain copy
  1. cout<< mp[“hello”]<<end;//查看”hello”出现的次数  
  2. mp[“hello”] ++ ;//”hello”出现的次数+1  
  3.   
  4. bool inMap = mp.count(“hello”); //”hello”是否在map中,返回0或1  
  5. inMap = (mp.find("hello") != mp.end()); //”hello”是否在map中,返回0或1  
  6.   
  7. for(it = mp.begin(); it != mp.end(); ++ it)//查找到”hello”,然后删除该元素  
  8. {  
  9.     if(it->first == "hello")  
  10.     {  
  11.         mp.erase(it);  
  12.         break;  
  13.     }  
  14. }  

7.  sort

头文件#include<algorithm>

使用sort可以很方便的对数组进行进行排序,它可以传两个或三个参数。第一个参数是要排序的区间首地址,第二个参数是区间尾地址的下一个地址,也就是排序的区间为[a,b),比如有一个数组 int a[5], 使得a[0] 到a[4]从小到大有序,只要写 sort(a, a + 5)就可以了,通用sort(a, a+ n);// n为元素个数。sort内部采用的是快速排序,一般情况下效率很高.

[cpp] view plain copy
  1. const int n = 3;  
  2. int arr[n] = {1, 3, 2};  
  3. sort(arr,arr+n);  
  4. for(int i = 0; i < n; ++ i)  
  5. cout<< arr[i] <<endl;  

另外,我们也可以按照自己的需求进行元素排序,元素可以是结构体,这里就用到了第三个参数,比较函数,告诉计算机按照什么顺序进行排序。

比如:按照从大到小排序

[cpp] view plain copy
  1. bool cmp(int a, int b)//定义比较函数,从大到小  
  2. {  
  3.     if(a >= b)  
  4.         return true;  
  5.     return false;  
  6. }  

主函数中: sort(arr, arr+n,cmp);

再比如下面结构体,要按照学生的年龄从小到大排序.

[cpp] view plain copy
  1. struct Student  
  2. {  
  3.     int age; //年龄  
  4.     string name;//姓名  
  5. }student[3];  
  6.   
  7. bool cmp(Student a, Student b)  
  8. {  
  9.     if(a.age <= b.age)  
  10.         return true;  
  11.     return false;  
  12. }  
  13.   
  14. student[0].name = "aa";student[0].age = 15;  
  15. student[1].name = "bb";student[1].age = 10;  
  16. student[2].name = "cc";student[2].age = 8;  
  17. sort(student, student+3, cmp);  
  18. for(int i = 0; i < 3; ++ i)  
  19. cout<< student[i].name <<"  "<<student[i].age<<endl;  

输出:

cc  8

bb 10

aa 15


8.  cmath

[cpp] view plain copy
  1. cout<< log2(8) <<endl;  //输出3 , 因为2的3次方为8  
  2. cout<< log10(100) <<endl;  //输出2,因为10的2次方为100  
  3. cout<< log(20) <<endl;  //计算 ln(20)的值  

补充:

[cpp] view plain copy
  1. //vector-----------------  
  2.    vector<int>v;  
  3.    v.erase(v.begin() + 2);//删除第2个元素,从0开始计数  
  4.    v.erase(v.begin() + 1, v.begin() + 5);//删除第1到第5个元素  
  5.    sort(v.begin(), v.end());//元素排序  
  6.    //sort(v.begin(), v.end(), cmp);//自定义排序规则,cmp函数自定义  
  7.    reverse(v.begin(), v.end());  
  8.   
  9.    //string-----------------  
  10.    string s;  
  11.    s = "123456";  
  12.    string::iterator it;  
  13.    it = s.begin();  
  14.    s.insert(it + 1, 'p');// s 变为 1p23456  
  15.    s.erase(it + 3);//删除第3个字符,从0开始计数  
  16.    s = "abc123456";  
  17.    s.replace(3, 3, "good");//从第3个开始,将连续的3个字符替换为"good",即将123替换为good  
  18.    reverse(s.begin(), s.end());  
  19.   
  20.    //set--------------------  
  21.    set<int>st;  
  22.    //反向遍历,从大到小  
  23.    set<int>::reverse_iterator rit;//定义反向迭代器  
  24.    for(rit = st.rbegin(); rit != st.rend(); rit ++)  
  25.    {  
  26.        cout << *rit << endl;  
  27.    }  
  28.   
  29.    //multiset--------------里面值可以重复  
  30.    multiset<int> ms;  
  31.    int n = ms.erase(3); //删除里面所有的3,返回删除元素总个数  
  32.    multiset<int>::iterator it;  
  33.    it = ms.find(3);  
  34.    if(it != ms.end())//找到了3这个元素  
  35.    {  
  36.        cout << *it <<endl;  
  37.    }  
  38.    else  
  39.    {  
  40.        cout<< "not find it"<<endl;  
  41.    }  
  42.   
  43.    //map-----------键值-->映照数据  
  44.    map<int> mp;  
  45.    mp.erase(2);//删除键值为2的元素  
  46.    map<int>::iterator it;  
  47.    it = mp.find(2);//查找键值  
  48.    if(it != mp.end())//找到了  
  49.    {  
  50.        cout << (*it).first << (*it).second <<endl;  
  51.    }  
  52.   
  53.    struct Info  
  54.    {  
  55.        string name;  
  56.        float score;  
  57.        //重载'<'操作符,自定义排序规则,在map中  
  58.        bool operator < (const Info &a) const  
  59.        {  
  60.            //按score从小到大排序  
  61.            return a.score < score;  
  62.        }  
  63.    };  
  64.   
  65.    map<Info, int> mmp;  
  66.   
  67.    //multimap------------允许键值相同的存在  
  68.    multimap<string, double>m;  
  69.    m.insert(pair<string, double> ("jack", 20.4));  
  70.    m.insert(pair<string, double> ("jack", 34.1));  
  71.    m.erase("jack");//删除键值等于"jack"的元素  
  72.    //find()函数只返回重复键值中的第一个元素的迭代器位置  
  73.   
  74.   
  75.    //deque-------------双端队列  
  76.    push_back()方法在尾部插入元素,不断扩张队列  
  77.    push_front()和insert()在首部和中间位置插入元素,只是将原位置上的元素值覆盖,不会增加新元素  
  78.    deque<int> d;  
  79.    d.push_back(1);  
  80.    d.push_back(2);  
  81.    d.push_back(3);  
  82.    d.insert(d.begin() + 1, 88);  
  83.    cout << d[0] << d[1] << d[2] <<endl; //输出 1 88 3  
  84.    d.pop_front();//头部删除元素  
  85.    d.pop_back();//尾部删除元素  
  86.    d.erase(d.begin() + 1);  
  87.   
  88.   
  89.    //list--------------链表  
  90.    list<int> l;  
  91.    l.push_back(2);  
  92.    l.push_back(1);  
  93.    l.push_back(5);//链表尾部插入元素,链表自动扩张  
  94.    l.push_front(8);//链表头部插入元素,链表自动扩张  
  95.    list<int>::iterator it;  
  96.    it = l.begin();  
  97.    it ++;//注意链表的迭代器只能进行 ++ 或者 -- ,不能 + n  
  98.    l.insert(it, 20);  
  99.    for(it = l.begin(); it != l.end(); it ++)  
  100.    {  
  101.        cout << *it <<endl;  //输出 8 20 2 1 5  
  102.    }  
  103.    l.remove(2);//值为2的节点都删除  
  104.    l.pop_front();//删除首部元素  
  105.    l.pop_back();//删除尾部元素  
  106.    l.sort();//排序  
  107.    l.unique();//剔除重复元素, 3 8 1 1 1 3 1 ---->  3 8 1 3 1  
  108.   
  109.   
  110.    //bitset 位集合容器  
  111.    bitset<10>b; //能容纳10个元素,也就是10位,默认都为0  
  112.    //赋值  
  113.    b[1] = 1;  
  114.    b[6] = 1;  
  115.    b[9] = 1;  
  116.    //第0位是最低位,第9位是最高位  
  117.    for(int i = b.size() - 1; i >= 0; i --)  
  118.    {  
  119.        cout << b[i] << " ";   //输出 1001000010  
  120.    }  
  121.    b.set();//全部重置为1  
  122.    b.set(1, 1);//将第1位置为1  
  123.    b.set(6, 1);  
  124.    b.set(9, 1);  
  125.    b.reset(9);//将第9位置为0  
  126.    cout << b <<endl;// 和上面效果相同,也是输出1001000010