C++中STL库函数的基本运用

学了这么长时间的STL库,现在我觉得是有必要对过去的题目和所遇到的问题做一下整理了,以便于之后更好的展开练习:

一、	为什么要用STL库?
        1、简单粗暴(省事)。
        2、便于解决复杂的问题(在贪心题目中显而易见)。
        3、使其思路更加广泛,解决问题的角度更多。
二、	怎么用STL库?
        1、设身处地的利用某个函数的特点进行解决问题。(下面会进行介绍各个函数的特点)
        2、做好第一点就足够了。
三、	各个函数的特点以及适合解决哪些问题?
        1、	vector:
            vector的强大之处就在于可以通过它完成建立邻接表,达到存图、存树的效果,之后利用DFS或者BFS的方式进行解决问题。
            最短路(包括其优化)中也会用到Vector.
            位置的不同也可以通过其进行存储:例如那道字符串的题目。
            (一个键对应好几个不同的值时,选择这个会很合适)。
        2、	set:
            set集合的强大之处莫过于它的去重、排序。
            尤其是去重,实在是十分之重要,当然,排序也很重要。
        3、	map:
            键值对:既一个键对应一个值(若要引用键或者值则需要迭代器)
            迭代器:map<int,int>::iterator it;(遍历时也需要)
            键:it->first,值:it->second;
            Map会根据键的大小进行自动排序,当有相同元素出现时,用数组的方式的话并不会替代之前已经存在的键值,用insert的方式进行插入的时候会替代已经存在的键值。
        4、	queue:
            利用队列实现BFS是队列的一个强大功能。
            单调队列也可以解决某些问题。
        5、	stack
            单调栈的应用极其广泛。
            单调栈适合解决不可排序的一组数,用来简化时间复杂度。
            利用某段数的单调性实现其效果。
        6、	priority_queue:
            优先级队列内部是通过堆进行实现的。
            下面会进行详细介绍。
四:各个函数的相关实现及其属性和方法。
    Vector:
        1.push_back   在数组的最后添加一个数据
        2.pop_back    去掉数组的最后一个数据 
        3.at                得到编号位置的数据
        4.begin           得到数组头的指针
        5.end             得到数组的最后一个单元+1的指针
        6.front        得到数组头的引用
        7.back            得到数组的最后一个单元的引用
        8.max_size     得到vector最大可以是多大
        9.capacity       当前vector分配的大小
        10.size           当前使用数据的大小
        11.resize         改变当前使用数据的大小,如果它比当前使用的大,者填充默认值
        12.reserve      改变当前vecotr所分配空间的大小
        13.erase         删除指针指向的数据项
        14.clear          清空当前的vector
        15.rbegin        将vector反转后的开始指针返回(其实就是原来的end-1)
        16.rend          将vector反转构的结束指针返回(其实就是原来的begin-1)
        17.empty        判断vector是否为空
        18.swap         与另一个vector交换数据
 
  3.2  详细的函数实现功能:其中vector<int> c.
    c.clear()                       移除容器中所有数据。
    c.empty()                       判断容器是否为空。
    c.erase(pos)                  删除pos位置的数据
    c.erase(beg,end)            删除[beg,end)区间的数据
    c.front()                        传回第一个数据。
    c.insert(pos,elem)           在pos位置插入一个elem拷贝
    c.pop_back()                  删除最后一个数据。
    c.push_back(elem)            在尾部加入一个数据。
    c.resize(num)                  重新设置该容器的大小
    c.size()                         回容器中实际数据的个数。
    c.begin()                         返回指向容器第一个元素的迭代器
    c.end()                            返回指向容器最后一个元素的迭代器
  set:
    begin()         返回set容器的第一个迭代器
    end()         返回set容器的最后一个迭代器
    clear()          删除set容器中的所有的元素
    empty()       判断set容器是否为空
    max_size()       返回set容器可能包含的元素最大个数
    size()        返回当前set容器中的元素个数
    rbegin       返回的值和end()相同
    rend()       返回的值和rbegin()相同
判断某个元素是否出现在set集合中的两种方法:
1、COUNT() 用来查找SET中某个某个键值出现的次数。这个函数在SET并不是很实用,因为一个键值在SET只可能出现0或1次,这样就变成了判断某一键值是否在SET出现过了。
示例代码:
    #include <iostream>  
    #include <set>    
    using namespace std;    
    int main()  {      

            set<int> s;      
            s.insert(1);      
            s.insert(2);      
            s.insert(3);      
            s.insert(1);      
            cout<<"set 中 1 出现的次数是 :"<<s.count(1)<<endl;      
            cout<<"set 中 4 出现的次数是 :"<<s.count(4)<<endl;      
            return 0;
      }  
2、	FIND()  ,返回给定值值得定位器,如果没找到则返回END()。
    #include <iostream>  
    #include <set>    
    using namespace std;    
    int main()  {      
        int a[] = {1,2,3};      
        set<int> s(a,a+3);      
        set<int>::iterator iter;      
        if((iter = s.find(2)) != s.end())      {         
            cout<<*iter<<endl;      
        }      
        return 0;  
   }  
#Set中的删除操作:#
        1、erase(iterator)  ,删除定位器iterator指向的值
        2、erase(first,second),删除定位器first和second之间的值
        3、erase(key_value),删除键值key_value的值

        #include <iostream>  
        #include <set>    
        using namespace std;    
        int main()  {      
        set<int> s;      
        set<int>::const_iterator iter;      
        set<int>::iterator first;      
        set<int>::iterator second;      
        for(int i = 1 ; i <= 10 ; ++i)      {          
            s.insert(i);      
        }      //第一种删除      
        s.erase(s.begin());      //第二种删除      
        first = s.begin();      
        second = s.begin();      
        second++;      
        second++;      
        s.erase(first,second);      //第三种删除      
        s.erase(8);      
        cout<<"删除后 set 中元素是 :";      
        for(iter = s.begin() ; iter != s.end() ; ++iter)      {          
            cout<<*iter<<" ";     
         }     
        cout<<endl;      
        return 0; 
}  
二分查找:
        lower_bound(key_value) ,返回第一个大于等于key_value的定位器
        upper_bound(key_value),返回最后一个大于等于key_value的定位器

        #include <iostream>  
        #include <set>    
        using namespace std;    
        int main()  {      
        set<int> s;      
        s.insert(1);      
        s.insert(3);      
        s.insert(4);      
        cout<<*s.lower_bound(2)<<endl;      
        cout<<*s.lower_bound(3)<<endl;      
        cout<<*s.upper_bound(3)<<endl;      
        return 0; 
       }  
Map:
        begin()         返回指向map头部的迭代器
        clear()        删除所有元素
        count()         返回指定元素出现的次数
        empty()         如果map为空则返回true
        end()           返回指向map末尾的迭代
        equal_range()   返回特殊条目的迭代器
        erase()         删除一个元素
        find()          查找一个元素
        get_allocator() 返回map的配置器
        insert()        插入元素
        key_comp()      返回比较元素key的函数
        lower_bound()   返回键值>=给定元素的第一个位置
        max_size()      返回可以容纳的最大元素个数
        rbegin()        返回一个指向map尾部的逆向迭代器
        rend()          返回一个指向map头部的逆向迭代器
        size()          返回map中元素的个数
        swap()           交换两个map
        upper_bound()    返回键值>给定元素的第一个位置
        value_comp()     返回比较元素value的函数
Queue:
        back()返回最后一个元素
        empty()如果队列空则返回真
        front()返回第一个元素
        pop()删除第一个元素
        push()在末尾加入一个元素
        size()返回队列中元素的个数
访问:
        q.front(),即最早被压入队列的元素。
        q.back(),即最后被压入队列的元素。
Privority_queue:
        入队 q.push();
        出队 q.pop();
        求队列中元素个数 q.size();    
        判断队列是否为空 q.empty();若为空返回true,否则返回false
        获得首元素 q.top();
        返回q的第一个元素  q.top();
        返回q的末尾元素 q.back();
优先级里最重要的东西:排序:
默认的优先队列 priority_queue <int> q;排序是由大到小的:

        #include<stdio.h>
        #include<queue>
        using namespace std;
        int main()
        {
            priority_queue<int> q;
            int num[5]={19,2,4,3,6};
            for(int i=0;i<5;i++)
                q.push(num[i]);
            for(int i=0;i<5;i++)
           {
                int temp=q.top();
                printf("%d ",temp);
                q.pop();
            }
            return 0;
        }
默认的优先队列(结构体,重载小于)
        #include<stdio.h>
        #include<queue>
        using namespace std;
        struct node
        {
            int x,y;
            bool operator < (const node & a) const      {
                return x<a.x;
            }
        }s;
        struct node
        {
            int x;
            int y;
            int time;
            friend bool operator < (node n1, node n2)     // 也可以用友元函数friend
            {
                return n1.time>n2.time;
            }
        };
        priority_queue <node> q;
        int main()
        {
            printf("读入:\n");
            for(int i=0;i<5;i++)
            {
               scanf("%d%d",&s.x,&s.y);
               q.push(s);
            }
            printf("输出:\n");
            while(!q.empty())
            {
                node temp=q.top();
                printf("(%d,%d) ",temp.x,temp.y);
                q.pop();
            }
            return 0;
        }
less是从大到小,greater是从小到大:
//升序队列
priority_queue <int,vector<int>,greater<int> > q;
//降序队列
priority_queue <int,vector<int>,less<int> >q;

//greater和less是std实现的两个仿函数(就是使一个类的使用看上去像一个函数。其实现就是类中实现一个operator(),这个类就有了类似函数的行为,就是一个仿函数类了)
优先级与结构体:

        #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){//返回true时,说明a的优先级低于b
							  //x值较大的Node优先级低(x小的Node排在队前)
							  //x相等时,y大的优先级低(y小的Node排在队前)
         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< 5; ++i ){
    	        int a,b;
    	        scanf("%d%d",&a,&b);
            	q.push({a,b});
	        } 
            while( !q.empty() ){
                cout << q.top().x << ' ' << q.top().y << endl;
                q.pop();
            }
           return 0;
        }
Stack:
        入栈,如例:s.push(x);
        出栈,如例:s.pop();注意,出栈操作只是删除栈顶元素,并不返回该元素。
        访问栈顶,如例:s.top()
        判断栈空,如例:s.empty() ,当栈空时,返回true。
        访问栈中的元素个数,如例:s.size() 。
posted @ 2020-01-21 21:08  IceSwords  阅读(1239)  评论(0编辑  收藏  举报