• 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("读入:
    ");
                for(int i=0;i<5;i++)
                {
                   scanf("%d%d",&s.x,&s.y);
                   q.push(s);
                }
                printf("输出:
    ");
                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() 。
    
    如果说年轻人未来是一场盛宴的话,那么我首先要有赴宴的资格。
  • 相关阅读:
    ASP.NET 高级编程基础第七篇—开发原则2
    反垃圾邮件引发的Email格式变异!
    .NET框架程序设计生成,打包,部署及管理应用程序与类型(2:Assembly的生成以及版本信息)
    .NET框架程序设计NET框架开发平台的体系架构概览(FCL,CTS,CLS)
    .NET框架程序设计生成,打包,部署及管理应用程序与类型(1:程序集的PE格式)
    [电影]蝴蝶效应
    .NET框架程序设计.NET框架开发平台的体系架构概览(.NET程序本质)
    [转贴]浅析.NET Framework对PE文件格式的扩展
    [MSDN今日讲座]Whidbey 开发系列讲座二:Visual Studio 2005团对开发系统简介
    郁闷!我的Gmail邮箱的问题!
  • 原文地址:https://www.cnblogs.com/prjruckyone/p/12225777.html
Copyright © 2020-2023  润新知