zoukankan      html  css  js  c++  java
  • [实用向]怎么使用STL容器中的一些操作

    对于源码的分析非常复杂,对STL的学习暂时留存

    这里简单罗列一些容器的使用和操作。

    (1)顺序容器

    1、array

    //array具有固定大小
    //初始化:
    array<int,42> a1;
    
    array<int,3>  a2 = {1,2,3} //列表初始化
    
    array<int,3> a3 = {1} //内部{1,0,0}

    Tip:内置数组类型不允许copy和赋值,但是array可以

    int a[3]  = {1,2,3};
    int b[3] = a //不行
    ------------------------
    array<int,3> a = {1,2,3};
    array<int,3> b = a; //ok,类型匹配即可

    2、操作

      初始化vector

    vector<int> a(n); //初始化了n个值,元素为0;
    vector<int> a(n,1); //初始化了n个值,元素为1;

    (非array)添加元素

    forward_list 有自己专属版本的insert和emplace,也不支持push_back和emplace_back
    
    vector和string不支持push_front和emplace_front。
    
    c.push_back(k)  //在c尾部创建一个值为t或由args创建的元素,返回void
    c.emplace_back(args)

    通常使用push_back()向容器中加入一个右值元素(临时对象)时,首先会调用构造函数构造这个临时对象,然后需要调用拷贝构造函数将这个临时对象放入容器中。原来的临时变量释放。这样造成的问题就是临时变量申请资源的浪费。 
    引入了右值引用,转移构造函数后,push_back()右值时就会调用构造函数和转移构造函数,如果可以在插入的时候直接构造,就只需要构造一次即可。这就是c++11 新加的emplace_back。

    关于俩者的区别。

    c.push_front(t)//在c头部创建一个值为t或者...,返回void
    c.emplace_front(args)
    
    //vector和string没有这俩操作
    //stack、queue、list是有的
    //forword_list 专属版本

    插入元素

    c.insert(p,t)
    c.emplace(p,args)
    
    //在迭代器p指向的元素之前创建一个值为t或由args创建的元素,返回指向新添加的元素的迭代器。
    
    c.insert(p,n,t)
    
    //同上,但是插入n个值为t的元素,返回指向第一个添加的元素的迭代器,如果n为0,返回p。
    
    c.insert(p,b,e)
    
    //在迭代器b和e指定的范围内的元素插入到迭代器p指向的元素之前。b和e不能指向c中的元素,返回指向新添加的第一个元素的迭代器,空,则返回p。
    
    c.insert(p,i1)
    
    //i1是一个花括号包围的元素值列表,讲这些给定值插入迭代器p指向的元素前,返回指向新添加的第一个元素的迭代器,空,返回p

    访问元素

    //back不适用与forward_list
    c.back();
    c.front
    
    
    //at操作和下标操作只适用于string,vector,deque和array
    c[n]
    c.at[n]

    删除元素

    //不适用与array,会改变array大小
    //forward_list有特殊版本的erase
    //forward_list不支持pop_back;
    //vector和string不支持pop_front
    
    c.pop_back()  //返回void,删除尾元素
    c.pop_front()  //返回void ,删除首元素
    c.erase(p)//删除迭代器p指定元素,返回一个指向被删除元素之后的迭代器,如果p指向尾元素,返回尾后迭代器(off-the-end),若p是尾后迭代器,无定义
    
    e.erase(b,e) //删除范围内元素,返回指向最后一个呗删除元素之后的有迭代器。若e本身是尾后迭代器,则函数返回尾后迭代器。
    
    
    c.clear() //删除c中所有元素,返回void

    2、特殊的forward_list

    //使用到再补充,来自primer c++ 5 p313页

    (2)关联容器

    map/set/multimp/multiset以及它们加前缀unordered的版本。

    //定义
    
    map<string,string> a;//空容器
    map<string,sting> b = 
    {{"studenta","A"},
      {"studentb","B"}};//{key-value}
    
    
    set<string> b;



    //找到元素容量

    b.size();//unordered_set等

    pair类型

    pair保存俩个数据成员
    pair<string,string> a;//数据成员是public的,分别命名为first和second,可以访问它们。
    
    
    
    pair<T1,T2> P;
    pair<T1,T2> P(v1,v2)
    pair<T1,T2>p = {v1,v2}  //等价于p(v1,v2)
    
    
    make_pair(v1,v2);//返回一个pair
    p.first
    p.second

    迭代器相关

    cbegin()和begin的区别是,前者返回一个const_iterator,可以++等,但不可以修改值

    遍历使用方法

    auto map_it = a.cbegin(); //a是一个map
    
    while(map_it !=a.cend()
    {
        cout<<map_it->first<<map_it->second<<endl;
        map_it++;
    }

    添加元素方法(关联容器)

    c.insert(v)  //v是一个value_type类型的对象。元素类型是pair
    c.emplace(args)//对于map和set来说,只有关键字不在,才会插入,返回一个pair,包含一个迭代器,指向具有指定关键字的元素,以及一个是否插入成功的bool值,而multi系列,总会插入,并返回一个指向新元素的迭代器。
    //举个例子
    
    word_count.insert({wrod,1});
    word_count.insert(make_pair(word,1));
    word_count.insert(pair<string,size_t>{word,1});
    word_count.insert(map<string,size_t>::value_type(word,1));
    
    
    c.insert(b,e)
    c.insert(il)   // 同之前顺序容器类似。

    删除元素

    c.erase(k)  //删除每个关键字为k的元素
    
    c.erase(p)  // 删除迭代器p指定的元素。返回指向p之后的元素迭代器
    
    c.erace(b,e)//删除范围,返回e。

    下标操作

    c[k] //返回关键字为k的元素,如果k不在c中,添加一个关键字为k的元素,对其值初始化
    
    c.at[k]  //访问关键字为k的元素,k不在,返回一个异常:out_of_range

    访问操作

    c.find(k) //返回一个迭代器,指向第一个关键字为k的元素,若k不在容器中,返回尾后迭代器

      unordered_set<char> lookup;

      lookup.find(s[i]) != lookup.end();//查找s[i]是不是在容器内。不在的话,就会返回尾后迭代器,也就是lookup.end(),这题可以看leetcode第三题。

    
    c.cout(k) //返回关键字等于k的元素数量,对于不允许重复的,值要么0要么1
    
    
    //注意lower_bound和upper_bound不适用于无序容器
    c.lower_bound(k)  //返回一个迭代器,指向第一个关键字不小于k的元素,也就是大于等于
    
    c.upper_bound(k) //返回一个迭代器,指向第一个关键字大于k的元素
    
    c.equal_range(k) //返回一个迭代器pair,表示关键字等于k的元素的范围,若k不存在,pair的俩个成员均等于c.end();

    (3)最后的最后,放上一道网易的编程体,涉及到map容器的使用。

    链接:https://www.nowcoder.com/questionTerminal/d73554145e4f443bb7d0a99d51dd6e5f
    来源:牛客网

    为了找到自己满意的工作,牛牛收集了每种工作的难度和报酬。牛牛选工作的标准是在难度不超过自身能力值的情况下,牛牛选择报酬最高的工作。在牛牛选定了自己的工作后,牛牛的小伙伴们来找牛牛帮忙选工作,牛牛依然使用自己的标准来帮助小伙伴们。牛牛的小伙伴太多了,于是他只好把这个任务交给了你。
    输入描述:
    每个输入包含一个测试用例。
    每个测试用例的第一行包含两个正整数,分别表示工作的数量N(N<=100000)和小伙伴的数量M(M<=100000)。
    接下来的N行每行包含两个正整数,分别表示该项工作的难度Di(Di<=1000000000)和报酬Pi(Pi<=1000000000)。
    接下来的一行包含M个正整数,分别表示M个小伙伴的能力值Ai(Ai<=1000000000)。
    保证不存在两项工作的报酬相同。


    输出描述:
    对于每个小伙伴,在单独的一行输出一个正整数表示他能得到的最高报酬。一个工作可以被多个人选择。
    示例1

    输入

    3 3 
    1 100 
    10 1000 
    1000000000 1001 
    9 10 1000000000

    输出

    100 
    1000 
    1001
    #include <iostream>
    #include <algorithm>
    #include <unordered_map>
    using namespace std;
      
    int main()
    {
        int N,M;
        cin >> N >> M;
        unordered_map<int,int> work;
        vector<int> Di;
        for(int i=0;i<N;i++)
        {
            int difficulty,Pi;
            cin>>difficulty>>Pi;
            Di.push_back(difficulty);
            work[difficulty] = Pi;
            //work.insert(pair<int,int>(Di,Pi));
        }
         
        //转换vector,使用vector做二分排序需要先排序,这里是升序
        sort(Di.begin(), Di.end());
         
        //替换掉高难度低报酬
        int pay = 0;
        for(auto iter = Di.begin();iter<Di.end();iter++)
        {
            if(pay < work[*iter])
                pay = work[*iter];
            else
                work[*iter] = pay;
        }
         
        //有序,二分查找找到最合适的
        for(int j =0;j<M;j++)
        {
            int Ai;
            cin>>Ai;
            auto iter =  upper_bound(Di.begin(),Di.end(),Ai);
            iter--;
            pay = work[*iter];
            cout<<pay<<endl;
        }
          
    }

    关于二分查找,在stl中有三个,下面博文介绍了这三个函数,有空会进行解析。

    https://blog.csdn.net/u010700335/article/details/41323427

  • 相关阅读:
    死锁
    Hibernate—01
    POI
    线程 Thread
    SSH页面整合_01
    cnblogs安家了
    漫画:天堂里没有程序员!
    我又愿中国青年都只是向上走,不必理会这冷笑和暗箭!!!!!!!!
    一位信息系统项目管理培训老师写的《论婚姻项目管理》值得看一下!
    程序员保持健康的方法和经验
  • 原文地址:https://www.cnblogs.com/EvansPudding/p/12568727.html
Copyright © 2011-2022 走看看