• [C++随笔录] vector使用


    通过上一篇文章 string的模拟实现, 其实我们就已经踏入了STL的门槛.
    STL容器的大致用法是差不多的 ⇒ 那我们这篇博客就讲一点跟string类不一样的新颖的东西

    初始化

    跟string一样, vector可以采用下面的形式初始化

    // 默认空间, 默认初始化
    vector<int> vec;
    
    // 开10个空间, 初始化为系统默认
    vector<int> vec(10);
    
    // 开10个空间, 初始化为1
    vector<int> vec(10, 1);
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    vector可以采用 迭代器区间初始化👇👇👇

    1. 采用同类型的迭代器区间
    vector<string> vs1;
    vs1.push_back("hello world");
    
    vector<string> vs2 (vs1.begin(), vs1.end());
    for (auto e : vs2)
    {
    	cout << e << " ";
    }
    cout << endl;
    
    *****
    hello world
    *****
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    1. 采用不同类型的迭代器区间
    vector<char> vc(5, 'b');
    
    vector<int> vs2(vc.begin(), vc.end());
    for (auto e : vs2)
    {
    	cout << e << " ";
    }
    cout << endl;
    
    *****
    98 98 98 98 98
    *****
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    1. 采用数组
    int a[5] = { 1,2,3,4,5 };
    vector<int> vi (a, a + sizeof(a) / sizeof(int));
    
    for (auto e : vi)
    {
    	cout << e << " ";
    }
    cout << endl;
    
    *****
    1 2 3 4 5
    *****
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    排序算法

    vector容器本身是没有 sort算法的, 但是算法库中是有 sort算法的, 头文件是
    👇👇👇

    int a[8] = { 11,25,3,14,5, 6, 18,20 };
    vector<int> vi (a, a + sizeof(a) / sizeof(int));
    
    sort(vi.begin(), vi.end());
    
    for (auto e : vi)
    {
    	cout << e << " ";
    }
    cout << endl;
    
    *****
    3 5 6 11 14 18 20 25
    *****
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    发现, 默认是升序的, 那么如何进行降序呢?

    int a[8] = { 11,25,3,14,5, 6, 18,20 };
    vector<int> vi (a, a + sizeof(a) / sizeof(int));
    
    greater<int> gt; // greater 仿函数对象
    sort(vi.begin(), vi.end(), gt);
    
    for (auto e : vi)
    {
    	cout << e << " ";
    }
    cout << endl;
    
    *****
    25 20 18 14 11 6 5 3
    *****
    
    int a[8] = { 11,25,3,14,5, 6, 18,20 };
    vector<int> vi (a, a + sizeof(a) / sizeof(int));
    
    less<int> l;
    sort(vi.begin(), vi.end(), l);
    
    for (auto e : vi)
    {
    	cout << e << " ";
    }
    cout << endl;
    
    *****
    3 5 6 11 14 18 20 25
    *****
    
    • 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

    上面的 greaterless 是两个仿函数, int 是 模版参数
    由于 sort是一个 函数模版 ⇒ 里面的参数是 对象
    那么greater 和 less两个仿函数也要传两个对象过去, 即 gtl
    ⇒ 由此, 我们可以得出: sort函数默认里面放的是less仿函数的对象

    由于里面传的是一个对象, 那么匿名对象也是可以的
    其实, 我们也可以这样写👇👇👇

    int a[8] = { 11,25,3,14,5, 6, 18,20 };
    vector<int> vi (a, a + sizeof(a) / sizeof(int));
    
    sort(vi.begin(), vi.end(), greater<int> ());
    
    for (auto e : vi)
    {
    	cout << e << " ";
    }
    cout << endl;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    其实, 如果要排降序, 我们也可以抖个机灵反向迭代器

    int a[8] = { 11,25,3,14,5, 6, 18,20 };
    vector<int> vi (a, a + sizeof(a) / sizeof(int));
    
    sort(vi.rbegin(), vi.rend());
    
    for (auto e : vi)
    {
    	cout << e << " ";
    }
    cout << endl;
    
    *****
    25 20 18 14 11 6 5 3
    *****
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    reverse和resize

    1. reverse — — 开空间
    2. resize — — 开空间 + 初始化

    基础不好的同学看到这里就有疑问了:
    🗨️ reverse 和 resize 的功能重复了, 要一个就可以了! 开空间是最重要的, 那要一个reverse就可以. 初始化啥的, 我们后面自己弄就行了

    • 其实, 这个问题, 我们在 string的模拟实现 中就有答案!
      先看下面的一个例子👇👇👇
    vector<int> vec;
    vec.reserve(10);
    
    for (int i = 0; i < 10; i++)
    {
    	vec[i] = i;
    }
    
    *****
    error
    *****
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    这是因为 operator[] 的实现中, 我们有一个断言 ⇒ assert(i < _size)
    这里, 我们开了10个空间 ⇒ _capacity = 10;
    但 _size(数据个数) = 0;
    ⇒ 由于断言, 我们是不能插入数据的

    如果要用 []来进行插入数据, 那么我们要用如下的方式👇👇👇

    vector<int> vec;
    vec.resize(10);
    
    for (int i = 0; i < 10; i++)
    {
    	vec[i] = i;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    那我们非要用 reverse 来进行插入数据, 那么我们不应该用 [], 而是用 push_back

    1. push_back 和 _size没有关系, 不够了也只是扩容而已
    2. push_back过后, _size是会进行++的
    vector<int> vec;
    vec.reserve(10);
    
    for (int i = 0; i < 10; i++)
    {
    	vec.push_back(i);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    由此, 我们可以得出:

    1. operator[] 是跟 _size 密切相关的
    2. push_back 的使用就比较宽松
    3. 并不是开好了空间, 就一定能进行插入数据的

    人需在事上磨,方可立得住,方能静亦定,动亦定. — ---- 王阳明
    译:有个学生问王阳明,安静的时候我感觉很不错,思想清晰,可一遇到事情就乱了阵脚,为什么?
    王阳明说:“这是你只知道静养,却没有下克己的功夫.这样一来,碰到事情就乱了阵脚. 人应该在具体的事情上磨炼自己,才能站得稳,才能静亦定,动亦定.

  • 相关阅读:
    安卓10添加修改serial串口的服务
    Spring对JUnit的支持
    26. Python数据类型之列表
    BSV 上的付费解密智能合约
    DAPS~5G NR双激活协议栈
    【Web前端】CSS详解(中篇)
    xxl-job调度的一致性及路由选择策略
    大数据相关积累
    测试工程师-入门指南
    ​LeetCode解法汇总2525. 根据规则将箱子分类
  • 原文地址:https://blog.csdn.net/qq_67549203/article/details/133134709