• STL


    STL 在广义上主要分为三类:
    1. algorithm(算法):完成特定的功能
    2. container(容器):用于存储数据
    3. iterator(迭代器): 类似于指针,用于访问容器中的内容

    STL - Algorithm(算法)

    STL 中大部分的算法都在 <algorithm> 库中,用的时候只需要在头文件中包含进来即可

    #include <algorithm>

    * 接下来介绍几个在程序中常使用的算法:

    STL - Algorithm(算法) - min, max(取最值)

    * min(x, y):取两者中的较小值
    * max(x, y):取两者中的最大值
    - 它们调用起来十分简单,只要满足 x,y 是相同类型,并
    可以比较大小即可。

    int a = 5, b = 4, c = min(a, b); // c = 4
    double x = 1.5, y = 3.5, z = max(x, y); // z = 3.5

    STL - Algorithm(算法) - swap(交换)

    * swap(x, y):交换两者的值
    - 调用时只要满足 x,y 是相同类型即可。

    int a = 5, b = 4;
    swap(a, b); // a = 4, b = 5
    double x = -1.0, y = 2.5;
    swap(x, y); // x = 2.5, y = -1.0
    // !swap(a, x) 无法调用:类型不相同

    STL - Algorithm(算法) - sort(排序)

    * sort(first, last):对于在 [first, last) 中的元素进行排序

    * sort(first, last, comp):对于在 [first, last) 中的元素进行排序,其中 comp 为比较器

    int a[10] = {5, 2, 1, 3, 4};
    sort(a, a+5);// a = [1, 2, 3, 4, 5, ...] 普通排序
    int cmp(int x, int y){return x > y;} // 比较器
    sort(a, a+5, cmp);// a = [5, 4, 3, 2, 1, ...] 从大到小排序
    int a[10] = {5, 2, 1, 3, 4};
    sort(a, a+5);// a = [1, 2, 3, 4, 5, ...] 普通排序

    * 几点需要注意的地方:排序的区间为[first, last),左闭右开
    如果需要排序A[1..5]中的数,则需要调用sort(A+1, A+6);
    * 可以自己定义比较器,作为排序的准则:例如,我们需要按照个
    位数来比较大小,则可以定义比较器为

    int cmp(int x, int y){return x % 10 < y % 10;}

    * 对于自己定义的结构体,可以定义自己的比较器来实现排序功能。

    // 以 a 为第一关键字,b 为第二关键字进行排序
    int cmp(Mystruct x, Mystruct y)
    {return x.a == y.a ? x.b < y.b : x.a < y.a;}

    STL - Algorithm(算法) - lower_bound (查找)

    * lower_bound(first, last, element):给定 [first, last)

    中的已经从小到大好排序的元素,找出最前的一个不比 element
    要小的元素的位置

    int a[10] = {5, 2, 1, 3, 4, 3, 2, 4};
    sort(a, a+8); // a = [1, 2, 2, 3, 3, 4, 4, 5] 已从小到大排好序
    int p2 = lower_bound(a, a+8, 2) - a; // p2 = 1
    // a中最前的不比 2 小的元素是: a[1] = 2
    int p4 = lower_bound(a, a+8, 4) - a; // p4 = 5
    // a中最前的不比 4 小的元素是: a[5] = 4
    int p0 = lower_bound(a, a+8, 0) - a; // p0 = 0
    // a中最前的不比 0 小的元素是: a[0] = 1
    int p6 = lower_bound(a, a+8, 6) - a; // p6 = 8
    // a中没有不比 6 小的元素,所以返回最后的一个位置 a[8]
    // 注意:a[8] 中并没有值,是数组的最末端

    STL - 容器 (Container)

    * STL 中的容器被分配在不同的库中,用的时候只需要在头文件中
    包含对应的库即可

    #include <vector> // 向量:用于存储连续的元素,类似数组
    #include <set> // 集合
    #include <queue> // 队列
    #include <stack> //
    #include <map> // 映射:相当于一个坐标无限大的数组
    #include <priority_queue> // 优先队列:类似于堆
    #include <list> // 列表:类似于链表

    * 接下来介绍几个在程序中常使用的容器。

    STL - 容器 (Container) - 向量 (vector)

    * 向量 (vector):用于存储连续的元素,类似数组;并且可以动态改变数组的大小(不必提前声明数组大小)

    //vector声明
    vector<int>a;
    vector<int>b(5, 0);
    
    int n;
    
    //vector访问
    void vis() {
        for(int i=0; i<5; i++) b[i] = i;
        for(int i=0; i<5; i++) cout<<b[i]<<" ";
        return ;
    }
    
    //vector添加元素 
    void add() {
        cin>>n;
        for(int i=0; i<n; i++) a.push_back(i * i);//尾部插入数字 
        for(int i=0; i<n; i++) cout<<a[i]<<" ";
        return ;
    }
    
    //插入元素
    a.insert(a.begin()+i,xx);  //在第i+1个元素前面插入xx 
    
    //删除元素
    a.erase(a.begin()+i); //第i+1个元素被删除
     
    //vector设定长度 
    vector<int>c;
    c.resize(5);//设置c的大小为5,下标 
    
    //vector长度(数组大小)
    int len = c.size(); //len = 5
    在此时c[4] 是可以访问的 
    
    //vector清空
    c.clear();//清空c数组 
    vector一旦清空,长度变为0,所以不可以访问c[4] 

    * 向量 (vector)还有更多的内置函数,这里就不再一一介绍;感
    兴趣可以访问www.cplusplus.com自行查阅相关内容。

    STL - 容器 (Container) - 二元组 (pair)

    * 二元组 (pair):用于存储二元组 (x,y)(并且 x,y 类型可以不相同)

    #include <algorithm>
    // pair 声明
    pair<int, int> a; // 声明一个二元组 a,用尖括号括起来
    pair<int, int> b(3, 4); // 声明一个二元组 b, x=3, y=4
    typedef pair<int, int> PI; // 使用类型定义
    PI c(5, 6); // 声明一个二元组 c
    // pair 访问
    int x = c.first, y = c.second; // x = 5, y = 6
    PI d = c; // 相同类型的二元组可以直接赋值
    c = PI(7, 8); // 重新赋值二元组
    d = make_pair(9, 10); // 另一种赋值方式

    * 二元组 (pair)的一个优点是可以直接比较大小;它会先比较第
    一关键字(x),再比较第二关键字(y)。

    可以自己定义cmp

    PI arr[10];
    for(int i=0; i<5; i++) arr[i] = PI(5 - i, i * i);
    sort(arr, arr+5);
    for(int i=0; i<5; i++)
    cout << "First␣element:" << arr[i].first << ""
    << "Second␣element:" << arr[i].second << endl;
    输出结果:
    First element:1 Second element:16
    First element:2 Second element:9
    First element:3 Second element:4
    First element:4 Second element:1
    First element:5 Second element:0

    * 通过二元组 (pair)可以把不同类型的元素给有机整合起来:

    三元组:

    typedef pair<int, PI> PII; // 定义三元组
    PII p = PII(2, PI(4, 8)); // 嵌套定义三元组
    cout << p.first << "," << p.second.first << ","
    << p.second.second << endl; // 嵌套输出
    typedef pair<string, int> People; // 定义字符串 -整数二元组
    People pa("Edward", 16);
    People pb("Bob", 17);
    if(pa > pb) swap(pa, pb); // 比较大小
    cout << pa.first << ":" << pa.second << endl; // 输出较小值

    STL - 容器 (Container) - 集合 (set)

    * 在集合 (set)中,可以像普通的集合一样,保存所有不同的数

    set<int> S; // 定义一个整型类型的 set
    for(int i=0; i<10; i++) S.insert(i*i); // 把 0-9 的平方数加入集合中
    set<int>::iterator p; // iterator:迭代器,相当于一个指针
    p = S.find(4); // 指针 -- 找到 4 所在位置
    cout << *p << endl; // 输出这个位置的值 -- 4
    ++p; // 指针后移
    cout << *p << endl; // 输出后一个平方数的值 -- 9

      输出结果:
      4
      9

    * 在集合 (set)中,可以支持查找一个数的位置:

    p = S.find(5); // 假如我们想要找一个集合中没有的数
    cout << "Notice␣:␣(5␣is␣not␣a␣square␣number)␣" << *p << endl;
    cout << (p == S.end()) << endl;
    // 就会返回一个特殊的指针:S.end() 结尾的指针
    // C++ 中的容器都是左闭右开的:
    // S.begin() 头指针 - 存放数据,S.end() 尾指针 - 不存放数据
    输出结果:
    Notice : (5 is not a square number) 10
    1

     如果要找的数不在集合里,输出集合里所有数的个数

    如果输出一个条件的话,如果满足条件输出1,不满足输出0

    * 在集合 (set)中,还有另一种方式查看一个数是否在集合中:~.count --> 判断某个值是否在数组中,如果在数组中为真,否则为假

    for(int i=0; i<10; i++)
    if(S.count(i)) cout << i << "␣is␣an␣element␣of␣S." << endl;
    else cout << i << "␣is␣not␣an␣element␣of␣S." << endl;
    // count(x),如果 x 存在则返回 1,不存在则返回 0
    输出结果:
    0 is an element of S.
    1 is an element of S.
    2 is not an element of S.
    3 is not an element of S.
    4 is an element of S.
    5 is not an element of S.
    6 is not an element of S.
    7 is not an element of S.
    8 is not an element of S.
    9 is an element of S.

    * 在集合 (set)中,亦可以直接支持lower_bound 操作:~.delete() --> 删除某个数  ;  ~.lower_bound() --> 寻找某个数

    p = S.lower_bound(20); // 假如我们想要找一个集合中不小于 20 的数
    cout << "The␣first␣element␣not␣lower␣than␣20:␣" << *p << endl;
    S.delete(p); // 删除一个数:使用指针的方式
    p = S.lower_bound(20); // 再次寻找
    cout << "The␣first␣element␣not␣lower␣than␣20:␣" << *p << endl;
    p = S.lower_bound(100); // 假如我们想要找一个集合中不小于 100 的数
    cout << (p == S.end()) << endl; // 假如没有数比它大,则返回尾指针
    输出结果:
    The first element not lower than 20: 25
    The first element not lower than 20: 36
    1

    STL - 迭代器 (Iterator)

    迭代器的运用:

    vector<int>::iterator vi; // 定义迭代器,直接在后面加::iterator
    vector<int> V; // 定义容器
    for(int i=1; i<10; i++) V.push_back(i * 3 - 2); // 新增值
    for(vi = V.begin(); vi != V.end(); ++vi) cout << *vi << "";
    cout << endl; // 按顺序输出容器中的值
    // 特殊的迭代器:V.begin(), V.end()(左闭右开)
    // 迭代器可以自增:往后挪一位
    // 不同容器的迭代器存在着区别
    输出结果:
    1 4 7 10 13 16 19 22 25
    // STL 中每个容器都有对应的迭代器。
    set<int> S; // 定义容器
    set<int>::iterator p; // 定义迭代器
    for(int i=0; i<10; i++) S.insert(i * i); // 插入平方数
    p = S.begin(), ++p;
    S.erase(p); // 第一种删除方式(迭代器) :删除第二个元素
    S.erase(49); // 第二种删除方式(值删除) :删除 49
    cout << "The␣Sequence␣:␣";
    for(p = S.begin(); p != S.end() ; ++p) cout << *p << "";
    cout << endl; // 顺序输出
    输出结果:
    The Sequence : 0 4 9 16 25 36 64 81

    迭代器两种删除方式

  • 相关阅读:
    人生应该接受的教育
    【转】俞军给淘宝产品经理的分享
    【转】伪O2O已死?2016年实体零售将迎来真正的O2O
    【转】一个测试工程师的2015总结和2016年小展望
    【转】移动App测试中的最佳做法
    Net作业调度(一) -Quartz.Net入门
    Quartz学习
    Newtonsoft.Json.dll
    用C#实现Base64处理,加密解密,编码解码
    mysql 连接数的最大数
  • 原文地址:https://www.cnblogs.com/wsdestdq/p/6817148.html
Copyright © 2020-2023  润新知