• c++ stl


    就是紫书上和网络上一部分内容的整理啦。

    不过说是整理,实际上还是挺乱的,而且是大一刚入学时候写的,挺乱,可能有点问题 o(╥﹏╥)o (*╹▽╹*)

    STL in ACM - To be an ACMan - 博客园

    stl 在 acm中的应用总结 - 若流芳千古 - 博客园

    紫书。stl初步 Standard Template Library

    1.排序与检索

    sort升序排序;

    compare函数;

    需要对结构体排序,就要定义<,或者compare

    对vector,用sort(v.begin(),v.end())

    upper_bound(i) 返回的是键值为i的元素可以插入的最后一个位置(上界)

    lowe_bound(i) 返回的是键值为i的元素可以插入的位置的第一个位置(下界)。

    lower_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于或等于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。

    upper_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。

    函数lower_bound()在first和last中的前闭后开区间进行二分查找,返回大于或等于val的第一个元素位置。如果所有元素都小于val,则返回last的位置

    举例如下:

    一个数组number序列为:4,10,11,30,69,70,96,100.设要插入数字3,9,111.pos为要插入的位置的下标

    pos = lower_bound( number, number + 8, 3) - number,pos = 0.即number数组的下标为0的位置。

    pos = lower_bound( number, number + 8, 9) - number, pos = 1,即number数组的下标为1的位置(即10所在的位置)。

    pos = lower_bound( number, number + 8, 111) - number, pos = 8,即number数组的下标为8的位置(但下标上限为7,所以返回最后一个元素的下一个元素)。

    所以,要记住:函数lower_bound()在first和last中的前闭后开区间进行二分查找,返回大于或等于val的第一个元素位置。如果所有元素都小于val,则返回last的位置,且last的位置是越界的!!~

    2.不定长数组vector  头文件,<vector>

    vector是模板类,需要用vector<int>a,vector<double>b,来声明数组。vector<string>类似于字符串数组;

    有a.size(),a.resize(),a.push_back()(尾部插入),a.pop_back(删除最后一个元素);clear清空,empty测试是否为空

        vector<int>v2(10);    //产生大小为10的vector

        vector<int>v3(10,-1);    //产生大小为10,并且每个元素都是-1的vector

        vector<int>v4(v3);        //用一个vector产生一个vecotr

    erase

    v.insert(v.begin(),8);//在最前面插入新元素。

        v.insert(v.begin()+2,1);//在迭代器中第二个元素前插入新元素

        v.insert(v.end(),3);//在向量末尾追加新元素。

    注意vector没有find,用的时候《algorithm》,find(v,begin(),v,end(),x)

    举例

    g[x] = vector<int>();赋空

    vector<int>a[30];  相当于二维数组,第二维大小不固定,每个a[i]都是vector,并且可以size,resize等操作

    a[b].push_back(b);  a[p].resize(h+1);

    vector<string>a,相当于string a[];//注意此时就是多个string  ,插入一个多一个,使用时为a[0],a[1]...

    vector<string>a[30]  ->插入时...          使用时 a[0][0],a[0][1]...      a[0].size,返回a[0][j]的个数

    for(int j=0;j<words[i].size();j++)

            {

                cout<<words[i][j];                //

    3.集合set 

    头文件,<set>      不重复,自动排序  set::find和set::insert消耗时间级别都为logN。所以,如果你确实需要保证插入和检索时间在logN,set可能是个不错的选择。

    和sort一样,自定义类型也可以构造set,但同样要定义<

    string <按字典序     

    .length .size用于string

    tolower(),<ctype>

    set的各成员函数列表如下:

    insert//只能这样插入!!

    begin()--返回指向第一个元素的迭代器

    clear()--清除所有元素

    . count()--返回某个值元素的个数

    empty()--如果集合为空,返回true

    end()--返回指向最后一个元素的迭代器

    erase()--删除集合中的元素                  //小心使用

    find()--返回一个指向被查找到元素的迭代器    .find(),返回的是被查找键的位置,没有则返回map.end()。;  s.find()//与vector不同

    例如:

    for (set<string>::iterator it = s.begin(); it != s.end(); it++)

        {

            string a = *it;

            for (int i = 1; i < a.length(); ++i)

            {

                if (s.find(a.substr(0, i)) != s.end() && s.find(a.substr(i, a.length() - i)) != s.end())//核心

                {

                    cout << a << endl;

                    break;

    string s("12345asdf");      //substr

    string a=s.substr(0,5);      //获得字符串s中 从第0位开始的长度为5的字符串//默认时的长度为从开始位置到尾,substr(j)就是从j到尾

    insert()--在集合中插入元素

    lower_bound()--返回指向大于(或等于)某值的第一个元素的迭代器

    size()--集合中元素的数目

    swap()--交换两个集合变量

    upper_bound()--返回大于某个值元素的迭代器    等等

    举例

    set<string>dict;

    while(ss>>buf)        ss>>buf, 每次只读一个串,以空格分隔。用While的意思,循环读每一个字符

      dict.insert(buf);

    迭代器 iterator类似于指针

    set<string>::iterator it=dict.begin();it!=dict.end();it++;

    cout<<*it<<endl;

    multiset:多重集合,其实就是 set 集合的扩展版。

    唯一的不同是 set 集合中一个值只能出现一次,

    而多重集合中一个值可以出现多次。

    一些需要注意的地方是:

    find均返回第一个匹配的位置,也就是说后面的不会返回     

    set::insert(key)的返回值是一个pair<iterator, bool>,其中pair中的bool成员表明了key被插入之前,set中是否已存在相同的key;也就是说,如果set中已经存在相同key的元素,那么插入操作是会失败的,新的元素不会被插进去;而multiset::insert的返回值只是一个iterator,插入操作总是会成功的。

            multiset::count(key)的返回值可能大于1。(因为插入了多个关键值)

            multiset::size()的返回值是多重集合的势(cardinality),即multiset中元素的个数,而不是值的个数。比如,{1, 1, 2}的size是3,而不是2。

            multiset::erase(key)会将对应的key全部删掉,所以对{1, 1, 2}调用erase(1)之后,它就变成了{2}。

            只要key存在于集合中,set::equal_range(key)的返回值pair<iterator1, iterator2>总是会有++iterator1 == iterator2。但是对multiset来说就不一定了。                   

    <algorithm>

    set_union  :两个区间必须是有序区间(从小到大)

    算法set_union可以用来求两个集合的并集,此处的集合可以为std::set,也可以是std::multiset,但是不可以是hash_set以及hash_multiset。为什么呢?因为set_union要求两个区间必须是有序的(从小到大排列),std::set和std::multiset为有序序列,而hash_set以及hash_multiset为无序序列。

      由于两个集合内的每个元素都不需唯一,因此,如果某个值在区间1中出现m次,在区间2中出现n次,那么该值在输出区间中会出现min(m,n)次,且全部来自于区间1.函数返回值为一个迭代器,指向输出区间的尾部。

    OutputIterator set_union(InputIterator1 first1,InputIterator1 last1,InputIterator2 first2,InputIterator2 last2,OutputIterator result)  返回值是指向最后

      std::vector<int> v(10);                      // 0 0 0 0 0 0 0 0 0 0

      std::vector<int>::iterator it;

      std::sort (first,first+5);    // 5 10 15 20 25

      std::sort (second,second+5);  // 10 20 30 40 50

      it=std::set_union (first, first+5, second, second+5, v.begin()); 

        // 5 10 15 20 25 30 40 50 0 0      //参数:求并集的两个集合(数组或者set等其他类型)的起止地址,最后一个参数是前两个集合并集的结果需要插入的地方

      v.resize(it-v.begin());                      // 5 10 15 20 25 30 40 50

    4.映射map  <map>

    使用count,返回的是被查找元素的个数。如果有,返回1;否则,返回0。注意,map中不存在相同元素,所以返回值只能是1或0。

    使用find,返回的是被查找元素的位置,没有则返回map.end()。

    从key(键)到value(值)的映射

    为了实现快速查找,map内部本身就是按序存储的(比如红黑树)。在我们插入<key, value>键值对时,就会按照key的大小顺序进行存储。这也是作为key的类型必须能够进行<运算比较的原因。

    如map<string,int>month_name;month_name["July"]=7;

    使用.count(),返回的是被查找键的个数。如果有,返回1;否则,返回0。注意,map中不存在相同元素,所以返回值只能是1或0。

    使用.find(),返回的是被查找键的位置,没有则返回map.end()。

            if(!cnt[r]) cnt[r] = 0;

            cnt[r]++;          可以记录string出现次数//第一次count,为0,

    find//与vector不同

    map<string,int>::iterator it;

    it=test.find("test0");

    cout<<"test0 find:";

    if(it==test.end()){

    cout<<"test0 not found"<<endl;

    }

    set_intersection

    intersection前务必对取交集的对象a和b进行sort

    OutputIt set_intersection( InputIt1 first1, InputIt1 last1,

                                InputIt2 first2, InputIt2 last2,

                                OutputIt d_first );

    4.5

    //注意,erase的参数为迭代器,三者都是,例如s.erase(s.find(b-a))//记住这样的操作;,set可以erase(k)待研究;remove有问题

    .end()返回的是最后一个元素后面一个位置,要用最后一个元素时,--

    迭代器不能+1,-1,+5.。。要用++,--

    5.栈,队列,优先队列

    栈  <stack>    stack<int>s,  .push(),  .pop()    .top()(取但不删除)  //注意,一般先top再pop

    队列<queue>  queue<int>s    deque  .back()  .pop_back;

    push(x) 将x压入队列的末端

    pop() 弹出队列的第一个元素(队顶元素),注意此函数并不返回任何值

    front() 返回第一个元素(队顶元素)    q.front()

    back() 返回最后被压入的元素(队尾元素)

    empty() 当队列为空时,返回true

    size() 返回队列的长度            queue不支持clear,用循环

    优先队列  先出队列的是优先级最高 的元素

    top()  返回优先队列中有最高优先级的元素

    priority_queue<int>pq  越小的整数优先级越低

    自定义类型也可以组成优先队列,但是要定义<符号

    也可以定义一个结构体cmp,重载()运算符,改变优先级  形如  priority_queue<int,vector<int>,cmp>pq

    struct cmp(){

    bool operator(){const int a,const int b)const{

    return a%10>b%10;

    }

    }

    对于常见的优先队列,stl有更简单的定义方法,如整数小,priority_queue<int,vector<int>,greater<int> >pq注意最后 > >不要写在一起

    copy    <algorithm> 可以用于复制

    //这三个参数要记住

      std::copy ( myints, myints+7, myvector.begin() );

      //参数      first  last      result 

      // [first,last)

    back_inserter:创建一个使用push_back的迭代器

    inserter:此函数接受第二个参数,这个参数必须是一个指向给定容器的迭代器。元素将被插入到给定迭代器所表示的元素之前。

    front_inserter:创建一个使用push_front的迭代器(元素总是插入到容器第一个元素之前)

    list<int> lst = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };

    list<int> lst2 ={10}, lst3={10},lst4={10};

    copy(lst.cbegin(), lst.cend(), back_inserter(lst2));

    //lst2包含10,1,2,3,4,5,6,7,8,9

    copy(lst.cbegin(), lst.cend(), inserter(lst3, lst3.begin()));

    //lst3包含1,2,3,4,5,6,7,8,9,10

    copy(lst.cbegin(), lst.cend(), front_inserter(lst4));

    //lst4包含9,8,7,6,5,4,3,2,1,10

    deque双端队列(uva210)

    6.测试stl

    <cstdlib>  rand (0,RAAND_MAX)至少为 32767 2^15-1;

    产生0-n,rand/RAND_MAX  *n;

    <ctime>  time_t t=time(null);  获取系统时间;  srand(time(null))

    vector尽量用引用方式

    assert宏,用法是assert(表达式),表达式为假时终止程序并给出错误信息;

    7.pair

    定义于头文件utility,iostream,vector。。。中,主要的作用是将两个数据组合成一个数据,两个数据可以是同一类型或者不同类型。

    pair<T1,T2> p1;

    pair<T1,T2> p1(v1,v2);

    make_pair(v1,v2);                          scanf("%d%d%d",&r,&a,&b);

                                                  for(i=a;i<=b;i++){

                                                  m[make_pair(r,i)]=-1;    //好用的初始化

    p1 < p2;

    p1 == p2;

    p.first;

    p.second;

    8.其他

    reverse 翻转  如reverse(str.bigin(),str.end) vec ...

  • 相关阅读:
    MySQL Connection排查未授权用户(unauthenticated user)
    Git常用命令
    abc
    更新显卡驱动
    财务模块 采购、接收、应付会计分录和功能认识
    ebs界面颜色改变
    获取科目的描述 创建科目
    EBS总账(GL)模块常用表
    收款 付款 到总帐
    PO收料到入库的分析
  • 原文地址:https://www.cnblogs.com/lqerio/p/11117601.html
Copyright © 2020-2023  润新知