zoukankan      html  css  js  c++  java
  • 关于C++标准模板库(STL)的一些基本使用

    vector

    vector可以理解成变长数组,即长度根据需要而自动改变的数组

    • 头文件:#include <vector>
    • 定义:vector<typename>name;
    • vector内可以通过下标或者迭代器(iterator)访问(只有vector和string才允许使用v.begin()+3这种迭代器加整数的写法)
    • v.push_back(value) 时间复杂度:$O(1)$
    • v.pop_back() 时间复杂度:$O(1)$
    • v.size() 返回的是unsigned类型 时间复杂度:$O(1)$
    • v.clear() 时间复杂度:$O(N)$ $N$是vector中元素的个数
    • v.insert(it,value) 时间复杂度:$O(N)$
    • v.erase(it) 时间复杂度:$O(N)$
    • v.erase(first,last) 即删除[first,last)内元素 时间复杂度:$O(N)$

     

    set

    set可以理解成集合,一个内部自动有序且不含重复元素的容器

    • 头文件:#include <set>
    • 定义:set<typename>name;
    • set只能通过迭代器访问
    • s.insert(value) 时间复杂度:$O(logN)$ $N$为set内元素个数
    • s.find(value) 时间复杂度:$O(logN)$ $N$为set内元素个数
    • s.erase(it) 时间复杂度:$O(1)$
    • s.erase(value) 时间复杂度:$O(logN)$
    • s.erase(first,last) 时间复杂度:$O(last-first)$
    • s.size() 时间复杂度:$O(1)$
    • s.clear() 时间复杂度:$O(N)$
    • set中元素是唯一的,如果需要处理不唯一的情况,则需要使用multiset。另外,C++11标准中还增加了unordered_set,以散列代替set内部的红黑树(一种自平衡二叉查找树),使其可以用来处理只去重但不排序的需求,速度比set要快得多。

     

    string

    string是装载字符串的容器

    • 头文件:#include <string>
    • 定义:string str = "abcd";
    • string可以通过下标和迭代器进行访问
    • 可以使用c_str()将string类型转换为字符数组进行输出 printf("%s ",str.c_str());
    • cin读入以遇到空格符便结束,getline(cin,str)以换行符为结束标志,因此可以读入空格
    • 使用'+' 可以拼接两个string。使用==,!=,<,<=,>,>=可以对两个string直接按照字典序进行比较
    • str.length() 或者 str.size() 可以返回string的长度 时间复杂度:$O(1)$
    • str.insert(pos,string) 时间复杂度:$O(N)$
    • str.insert(it,it2,it3) it为目的字符串的插入位置迭代器 it2和it3为待插字符串的首尾迭代器[it2,it3) 时间复杂度:$O(N)$
    • str.erase(it) 时间复杂度:$O(N)$
    • str.erase(first,last) 时间复杂度:$O(N)$
    • str.erase(pos,length) pos为开始删除的初始位置,length为删除字符的个数 时间复杂度:$O(N)$
    • str.clear() 时间复杂度:$O(1)$
    • str.substr(pos,len) 返回从pos开始,长度为len的子串 时间复杂度:$O(len)$
    • string::npos 这是一个常数,本身的值为-1,但由于是unsigned_int类型,因此也可以认为是unsigned_int类型最大值即4294967295。string::npos用作find()失配时的返回值。
    • str.find(str2) 返回str2在str中第一次出现的位置 或者 返回 string::npos 时间复杂度:$O(nm)$ 其中n和m分别为str和str2的长度
    • str.find(str2,pos) 从str的pos位开始匹配 同str.find(str2) 时间复杂度:$O(nm)$
    • str.replace(pos,len,str2) 把str从pos号位开始、长度为len的子串替换为str2 时间复杂度:$O(str.length())$
    • str.replace(it1,it2,str2) 把str[it1,it2)范围的子串替换为str2 时间复杂度:$O(str.length())$

     

    map

    map可以将任何基本数据类型(包括STL容器)映射到任何基本类型(包括STL容器),但若要表示字符串的话只能用string,而不能用char数组。

    • 头文件:#include <map>
    • 定义:map<typename1,typename2> m; typename1称为键 typename2称为值
    • map会按键的大小顺序自动排序,这是因为map内部是以红黑树实现的
    • m.find(key) 返回键为key的映射的迭代器,时间复杂度:$O(logN)$ N是map中映射的个数
    • m.erase(it) 时间复杂度:$O(1)$
    • m.erase(key) 时间复杂度:$O(logN)$ N是map中映射的个数
    • m.erase(first,last) 时间复杂度:$O(last-first)$
    • m.size() 时间复杂度:$O(1)$
    • m.clear() 时间复杂度:$O(N)$ N是map中元素的个数
    • mup的键和值是唯一的,如果一个键需要对应多个值,可以使用multimap。另外C++11标准中增加了unordered_map,以散列代替内部的红黑树实现,使其可以用来处理只映射而不按key排序的需求,速度比map要快得多

     

    queue

    queue实现了一个FIFO(先进先出)的容器

    • 头文件:#include <queue>
    • 定义:queue<typename> q;
    • queue中只能通过 q.front()来访问队首元素,q.back()来访问队尾元素 时间复杂度均为:$O(1)$
    • q.push(value) 时间复杂度:$O(1)$
    • q.pop() 时间复杂度:$O(1)$
    • q.empty() 时间复杂度:$O(1)$
    • q.size() 时间复杂度:$O(1)$
    • 使用q.front() 和 q.pop() 之前必须用q.empty()判断queue是否为空

     

    priority_queue

    priority_queue指优先队列,原理是用堆实现。在优先队列中,队首元素一定是优先级最高那个,然后这个优先级可以自己定义。

    • 头文件:#include <queue>
    • 定义:priority_queue<typename> pq;
    • priority_queue只能通过pq.top()来访问队首元素,之前要用pq.empty()进行判断 时间复杂度:$O(1)$
    • pq.push(value) 时间复杂度:$O(logN)$ N是当前队列里的元素个数
    • pq.pop() 记得之前要用pq.empty()进行判断 时间复杂度:$O(logN)$
    • pq.empty() 时间复杂度:$O(1)$
    • pq.size() 时间复杂度:$O(1)$
    • 当优先队列里面的元素为基本数据类型(int,double,char等等)时,默认是数字或字典序越大优先级越高所以越排在前面,而且以下两种定义是等价的:priority_queue<int> pq  以及 priority_queue<int,vector<int>,less<int> > pq,可以发现第二种定义方法多了两个参数,vector<int>是用来承载底层数据结构堆(heap)的容器,vector的数据类型与优先队列的保持一致,less<int>则是对第一个参数的比较类,less<int>表示数字越大优先级越大,相反,greater<int>表示数字越小优先级越大。
    • 然后讲如果数据类型是一个结构体的时候怎样设置优先级,当然当前类型即使是基本数据类型也可以使用这种方法,只不过第三个参数的写法不一样了。
    struct fiuit
    {
        string name;
        int price;
        friend bool operator < (fruit f1,fruit f2)
        {
            return f1.price < f2.price;
        }
    };

    现在希望按水果的价格高的为优先级高,那么就需要重载小于号"<",注意重载大于号会编译错误,因为从数学上来说只需要重载小于号,即$f1>f2$等价于判断$f2<f1$,而$f1==f2$等价于判断$!(f1<f2)&&!(f2<f1)$,函数内为return f1.price < f2.price ,因此重载后小于号还是小于号的作用。此时就可以直接定义fruit类型的优先队列:priority_queue<fruit> pq 其内部就是以价格高的水果为优先级高。相反,如果想以价格低的水果为优先级高,只要把return中的<改为>即可。没错,他们效果看上去与直觉相违背,不过语法上就是这样写的。我们可以理解成优先队列默认优先级高的在队首,那么假若我们把<改为>,则相当于把规则翻转了,那么原先大值优先也自然变成了小值优先。
    还有一种方法是把重载的函数放在结构体外面:

    struct cmp
    {
        bool operator () (fruit f1,fuit f2)
        {
            return f1.price < f2.price;
        }
    };

    可以看到我们去掉了friend(友元),然后把<改为了一对小括号,记得要用struct把所有包起来。
    还有在这个时候我们就不能写priority_queue<fruit> pq 来定义优先队列了,要改为priority_queue<fruit,vector<fruit>,cmp > pq 可以看到这跟上面基本元素的定义方法其实是可以差不多的。哪怕数据类型是其他STL容器也可以用这种重载符号的方法来使用priority_queue。
    最后,如果结构体内的数据较大(使用了字符串或者很大的数组),我们可以使用“引用”来提高效率,即加上const和&,如下:

    friend bool operator < (const fruit &f1,const fruit &f2)
    {
        return f1.price < f2.price;
    }
    
    // 两种重载方法 
    
    bool operator () (const fruit &f1,const fruit &f2)
    {
        return f1.price < f2.price;
    }

    stack

    stack是一个实现LIFO(后进先出)的容器。

    • 头文件:#include <stack>
    • 定义:stack<typename> s
    • stack中只能通过s.top()来访问栈顶元素 时间复杂度:$O(1)$ 注意先用s.empty()检测是否栈为空
    • s.push(value) 时间复杂度:$O(1)$
    • s.pop() 时间复杂度:$O(1)$
    • s.empty() 时间复杂度:$O(1)$
    • s.size() 时间复杂度:$O(1)$

     

    pair

    pair相当于一个内部有两个可以自定类型的元素的结构体(而不是真的需要用struct去实现,pair使这看起来更优美)。

    • 头文件:#include <utility> 值得注意的是map头文件包含utility头文件,记不住可以用map头文件代替,这也说明了map的内部实现用到了pair
    • 定义:pair<typename1,typename2> p  也可以同时进行初始化:pair<string,int> p("hello",5);
      如果想临时构建一个pair有两种方法:pair<string,int>("hello",5) 或者使用自带的make_pair("hello",5)
    • 关于pair中元素的访问跟结构体差不多,p.first 和 p.second
    • 两个pair类型数据可以直接用==、!=、<、<=、>、>=比较大小,规则是先比较first的大小,只有当first相等的时候才会去比较second的大小
    • pair常用来作为map的键值对数据

     

  • 相关阅读:
    oracle 开发 第16章 SQL优化
    oracle 开发 第13章 数据库对象
    oracle 开发 第14章 集合
    oracle 开发 第15章 大对象
    IDEA创建springboot项目失败问题解决
    redis事务 学习笔记
    redis通信协议 学习笔记
    运行报caused by: redis.clients.jedis.exceptions.JedisConnectionException: Failed connecting to host错
    redis主从同步(复制+哨兵) 学习笔记
    redis限流redis-cell模块安装 笔记
  • 原文地址:https://www.cnblogs.com/kachunyippp/p/10256679.html
Copyright © 2011-2022 走看看