• STL标准模板库


    Standard Library 标准库

    Standard Template Library 标准模板库

    1. 容器 containers

    2. 迭代器 iterators

    3. 算法 algorithms

    4. 函数器 functional

    0.1 函数模板、类模板 与 * 乘法运算符 重载

    #include
    // 函数模板
    template<typename T>
    T square(T x){
      return x*x;
    }
    // 类模板
    template<typename T>
    class BoVector{
    // class 默认为 provide 私有 类型
      T arry[1000];// 初始数组容量
      int size;    // 实际存储数据数量
    public:
      BoVector(): size(0) {}; // 类默认构造函数 初始化 size=0
      void push(T x){ arry[size] = x; size++; } // 插入数据
      T get(int i) const {return arry[i]; }// 需要是否越界检查
      int getsize() const {return size;}
      void print() const { for(int i=0; i<size; i++){std::cout << arry[i] << std::endl;} }
    };
    
    // 类的BoVector  * 运算符 重载
    template<typename T>
    BoVector<T> operator*(const BoVector<T>& bv1, BoVector<T>& bv2){
      BoVector<T> ret;
      for(int i=0; i<bv1.getsize(); i++){
        ret.push(bv1.get(i) * bv2.get(i));
      }
      return ret;
    }
    
    
    int main(){
      std::cout << square(5) << std::endl;   // square(5) 函数模板 模板类型可省略, 会自己的推断
      std::cout << square(5.5) << std::endl; // square(5.5)
    
      BoVector<int> bv;// 类模板的模板类型不可省略
      bv.push(1);
      bv.push(2);
      bv.push(3);
      bv.push(4);
      bv.print();// bv = {1,2,3,4}
    
      bv = square(bv); // 模板函数 --> 乘法运算符重载
      bv.print();      // bv = {1,4,9,16}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46

    0.2容器 迭代器 算法 示例

    #include// std::cout & std::endl 
    #include  // std::vector
    #include// std::sort
    using namespace std;
    
    int main(){
    // 容器========
    	vector<int> vec_i;
    	vec_i.push_back(5);
    	vec_i.push_back(2);
    	vec_i.push_back(0); // vec_i = (5, 2, 0);
    // 迭代器======
    	vector<int>::iterator iter_beg = vec_i.begin(); // [begin, end) 左闭右开区间
    	vector<int>::iterator iter_end = vec_i.end();
    
        for(vector<int>::iterator it = iter_beg; it!=iter_end; ++it){
    		cout << *it << endl;// vec_i = (5, 2, 0);
    	}
    // 算法========
            // 算法 通过 迭代器 对 容器元素 进行操作 !!!!!!!!!!!!!!!
    	sort(iter_beg+1, iter_end);//vec_i = (5, 0, 2);
    	
        for(vector<int>::iterator it = iter_beg; it!=iter_end; ++it){
    		cout << *it << endl;
    	}
    	
    	sort(iter_beg, iter_end);//vec_i = (0, 2, 5);
    	for(vector<int>::iterator it = iter_beg; it!=iter_end; ++it){
    		cout << *it << endl;
    	}
    	
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    1. 容器

    1.1 序列容器

    vector向量 deque双向队列 双向链表list 单向链表forward_list array数组
    #include  
    #include 
    #include 
    #include 
    #include 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    a. vector向量 动态数组

        |||  ........... -----> 
    
    • 1
    
    /*
    1. 在向量尾部 插入/删除元素 特别快 O(1)
    2. 在向量头部 或者 中间插入元素 特别慢 O(n)
    3. 在向量中查找一个元素特别慢 O(n)
    |||  ........... ----->
    头            尾
    */
    #include
    #include
    using namespace std;
    
    int main(){
    
    	vector<int> vec_i;  // vec_i.size() == 0
    	vec_i.push_back(5);
    	vec_i.push_back(2);
    	vec_i.push_back(0); // vec_i = {5, 2, 0}, vec_i.size() == 3
    
    // 访问数据 随机访问
        cout << vec_i[2] << endl;    // 0, []访问,无范围检查
        cout << vec_i.at(1) << endl; // 2, .at()访问,会进行范围检查,访问速度稍慢,但是安全
        
    // 通过 索引 遍历元素
        for(int i = 0; i < vec_i.size(); ++i){
        	cout << vec_i[i] << " "; //确定索引不会超范围,就用索引访问  vec_i.at(i)
        }
        cout << endl;
        
    // 通过迭代器 遍历元素
        for(vector<int>::iterator iter = vec_i.begin(); iter != vec_i.end(); ++iter){
        	cout << *iter << " "; // 对迭代器进行解引用得到
        }
        cout << endl;
        
    //范围for c++ 11 遍历元素
    //    for(item:vec_i){
    //   	cout << item << " ";
    //    }
    //    cout << endl;
    
    // 指针访问
    	int* p = &vec_i[0];
    	for(int i = 0; i < vec_i.size(); ++i){
    		cout << p[i]<< " ";
    	}
        cout << endl;
        
    // 部分容器的成员函数
    	if(vec_i.empty()) cout << "vec_i has no num" << endl; // 是否包含元素
    	
    	cout << vec_i.size() << endl; // 存储的元素数量
    	
    	vector<int> vec_i2(vec_i); // 拷贝初始化, vec_i2 = {5, 2, 0}
    	
    	vec_i.clear(); // 清空元素 vec_i.size() == 0
    	
    	vec_i2.swap(vec_i); // 两向量交换元素,vec_i2.size() == 0, vec_i = {5, 2, 0}
        
        
    	return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63

    b. deque 双向队列

    <-----|..................|----->
         队首               队尾 
    
    • 1
    • 2
    /*
    1. 在队列 头部和尾部插入元素,特别快 O(1)
    2. 在队列中间插入元素,特别慢 O(n)
    3. 在队列中查找元素,特别慢 O(n)
    <-----|..................|----->
         队首               队尾 
    */
    
    #include
    using namespace std;
    deque<int> deq = {5, 2, 0};
    deq.push_back(5);  // 队尾  插入 {5, 2, 0, 5}
    deq.push_front(0); // 队首  插入 {0, 5, 2, 0, 5}
    
    // 其他接口和 vector 的类似
    cout << deq[1] ; // 5
    cout << deq.at(2) ;// 2
    deque<int>::iterator iter = deq.begin() + 3;
    cout << *iter ; // 0
    // size() empty()  clear() swap()
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    c.双向链表list

     双向链表,包含前后指针,和数据域,数据不连续,浪费访存,多包含两个指针变量,浪费内存
    
    • 1
    /*
    1. 在链表中任意位置插入/删除 元素 特别快 O(1)
    2. 在链表中查找元素 特别慢, O(n), 实际上因为内存不连续,浪费访存case,比vector慢了很多
    3. 无随机访问 [] 以及 .at()
    4. splice() 实现list拼接的功能。将源list的内容部分或全部元素删除,拼插入到目的list。 O(1)
    */
    #include
    #include // std::find
    #include
    using namespace std;
    int main(){
    
    list<int> mylist = {5, 2, 0};
    mylist.push_back(1);
    mylist.push_back(3);
    mylist.push_back(1);
    mylist.push_back(4);// {5, 2, 0, 1, 3, 1, 4};
    
    mylist.push_front(5);// {5, 5, 2, 0, 1, 3, 1, 4};
    
    // 查找元素2
    list<int>::iterator itr = find(mylist.begin(), mylist.end(), 2);// itr --->2
    
    cout << *itr << endl;
    // 插入元素6   链表插入速度特别快
    mylist.insert(itr,6);// {5, 5, 6, 2, 0, 1, 3, 1, 4};// 在2的前面一个位置插入6
    cout << *itr << endl;
    
    itr++; // 指向 0
    cout << *itr << endl;
    
    // 删除 itr指向的元素   速度特别快 O(1)
    mylist.erase(itr);// {5, 5, 6, 2, 1, 3, 1, 4};
    cout << *itr << endl; // 但是内存还存在 0元素
    
    for(list<int>::iterator itr1 = mylist.begin(); itr1 != mylist.end();++itr1){
    	cout << *itr1 << endl;
    }
    
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    d. 单向链表forward_list

    e. array数组

    1.2 有序关联容器(红黑二叉树)

    set, multiset 单值树集合  multi 关键字可以重复出现
    map, multimap 配对双值树集合
    
    #inlcude
    #inlcude
    #inlcude
    #inlcude
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    1.3 无序关联容器(哈希表)

    unordered set/multiset  单值桶集合
    unordered map/multimap  配对双值桶集合 
    
    #inlcude
    #inlcude
    #inlcude
    #inlcude
    
    // 和另一个库里的类似
    hash_map
    hash_set
    hash_multimap
    hash_multiset
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
  • 相关阅读:
    OSPF开放最短路径优先(Open Shortest Path First)协议
    linux常用的命令
    模糊搜索利器:Python的thefuzz模块详解
    无涯教程-JavaScript - MROUND函数
    深度学习知识点:循环神经网络(RNN)、长短期记忆网络(LSTM)、门控循环单元(GRU)
    闲人闲谈PS之三十四——项目成本费用控制阈值
    nginx代理后如何获取用户真实访问的ip,以及访问耗时接口是nginx报504问题处理
    为什么基于树的模型在表格数据上仍然优于深度学习
    深入理解递归算法:从基础到实践
    JavaScript笔记8-DOM中的事件、获取元素、操作元素
  • 原文地址:https://blog.csdn.net/RuanJian_GC/article/details/133364052