锋盈数科-知识库 Logo
首页
软件开发
计算机基础
Hello Halo
新手必读
关于本知识库
登录 →
锋盈数科-知识库 Logo
首页 软件开发 计算机基础 Hello Halo 新手必读 关于本知识库
登录
  1. 首页
  2. 软件开发
  3. C++STL详解+代码分析+典例讲解

C++STL详解+代码分析+典例讲解

0
  • 软件开发
  • 发布于 2024-09-21
  • 0 次阅读
黄健
黄健

vector 的介绍:

1、vector是表示可变大小数组的序列容器。
2、vector就像数组一样,也采用的连续空间来存储元素,这也意味着可以采用下标对vector的元素进行访问。
3、vector与普通数组不同的是,vector的大小是可以动态改变的。
4、当vector需要重新分配大小时,其做法是,分配一个新的数组,然后将全部元素移到这个数组当中,并释放原来的数组空间。
5、vector分配空间策略:vector会分配一些额外的空间以适应可能的增长,因此存储空间比实际需要的存储空间一般更大。不同的库采用不同的策略权衡空间的使用和重新分配,以至于在末尾插入一个元素的时候是在常数的时间复杂度完成的。
6、由于vector采用连续的空间来存储元素,与其他动态序列容器相比,vector在访问元素的时候更加高效,在其末尾添加和删除元素相对高效,而对于不在其末尾进行的删除和插入操作效率则相对较低。

vector 的使用

1.定义方式

法一:构造一个某类型的空容器。

vector<int> v1; //构造int类型的空容器

法二:构造一个含有n个val的某类型容器。

vector<int> v2(10, 2); //构造含有10个2的int类型容器

法三:拷贝构造某类型容器的复制品

vector<int> v3(v2); //拷贝构造int类型的v2容器的复制品

法四:使用迭代器拷贝构造某一段内容。

vector<int> v4(v2.begin(), v2.end()); //使用迭代器拷贝构造v2容器的某一段内容

注意:该方式也可用于拷贝其他容器的某一段内容。

string s("hello world");
vector<char> v5(s.begin(), s.end()); //拷贝构造string对象的某一段内容

vector的空间增长问题

size和capacity

通过size函数获取当前容器中的有效元素个数,通过capacity函数获取当前容器的最大容量。

#include <iostream>
#include <vector>
using namespace std;

int main()
{
    vector<int> v(10, 2);
    cout << v.size() << endl; //获取当前容器中的有效元素个数
    cout << v.capacity() << endl; //获取当前容器的最大容量
    return 0;
}

reserve和resize

通过reserse函数改变容器的最大容量,resize函数改变容器中的有效元素个数。
reserve规则:
 1、当所给值大于容器当前的capacity时,将capacity扩大到该值。
 2、当所给值小于容器当前的capacity时,什么也不做。
resize规则:
 1、当所给值大于容器当前的size时,将size扩大到该值,扩大的元素为第二个所给值,若未给出,则默认为0。
 2、当所给值小于容器当前的size时,将size缩小到该值。

#include <iostream>
#include <vector>
using namespace std;

int main()
{
    vector<int> v(10, 2);
    cout << v.size() << endl; //10
    cout << v.capacity() << endl; //10
    v.reserve(20); //改变容器的capacity为20,size不变
    cout << v.size() << endl; //10
    cout << v.capacity() << endl; //20
    v.resize(15); //改变容器的size为15
    cout << v.size() << endl; //15
    cout << v.capacity() << endl; //20
    return 0;
}

empty

通过empty函数判断当前容器是否为空。

#include <iostream>
#include <vector>
using namespace std;

int main()
{
    vector<int> v(10, 2);
    cout << v.empty() << endl;
    return 0;
}

vector的迭代器使用

begin和end

通过begin函数可以得到容器中第一个元素的正向迭代器,通过end函数可以得到容器中最后一个元素的后一个位置的正向迭代器。

#include <iostream>
#include <vector>
using namespace std;

int main()
{
    vector<int> v(10, 2);
    //正向迭代器遍历容器
    vector<int>::iterator it = v.begin();
    while (it != v.end())
    {
        cout << *it << " ";
        it++;
    }
    cout << endl;
    return 0;
}

比方说这道题中,在一行中需要,排序,我们这里使用了迭代器

rbegin和rend

通过rbegin函数可以得到容器中最后一个元素的反向迭代器,通过rend函数可以得到容器中第一个元素的前一个位置的反向迭代器。
反向迭代器遍历容器:

#include <iostream>
#include <vector>
using namespace std;

int main()
{
    vector<int> v(10, 2);
    //反向迭代器遍历容器
    vector<int>::reverse_iterator rit = v.rbegin();
    while (rit != v.rend())
    {
        cout << *rit << " ";
        rit++;
    }
    cout << endl;
    return 0;
}

vector的增删查改

push_back和pop_back

通过push_back函数对容器进行尾插,pop_back函数对容器进行尾删。

#include <iostream>
#include <vector>
using namespace std;

int main()
{
    vector<int> v;
    v.push_back(1); //尾插元素1
    v.push_back(2); //尾插元素2
    v.push_back(3); //尾插元素3
    v.push_back(4); //尾插元素4

    v.pop_back(); //尾删元素
    v.pop_back(); //尾删元素
    v.pop_back(); //尾删元素
    v.pop_back(); //尾删元素
    return 0;
}

这里的应用非常广,尤其在字符串那一块,这里给大家整一道相关的编程题

如果用上述我说的来解决的话

#include<bits/stdc++.h>
using namespace std;
int main()
{
    string s, t;
    cin >> s >> t;
    int q;
    cin >> q;
    while (q--)
    {
        string s1, t1;

        int l1, r1, l2, r2;
        cin >> l1 >> r1 >> l2 >> r2;
        for (int i = l1-1; i <= r1-1; i++)
        {
            s1.push_back(s[i]);
        }
        for (int i = l2 - 1; i <= r2-1; i++)
        {
            t1.push_back(t[i]);
        }
        if (s1 > t1)
            cout << "erfusuer"<<endl;
        else if (s1 < t1)
        {
            cout << "yifusuyi" << endl;
        }
        else
            cout << "ove"<<endl;
        s1 = "";
        t1 = "";

    }
    return 0;
}

即可依葫芦画瓢解决,详解在我之前发的字符串的编程题有解释,若代码看不懂可以往前看。

insert和erase

通过insert函数可以在所给迭代器位置插入一个或多个元素,通过erase函数可以删除所给迭代器位置的元素,或删除所给迭代器区间内的所有元素(左闭右开)。

#include <iostream>
#include <vector>
using namespace std;

int main()
{
    vector<int> v;
    v.push_back(1);
    v.push_back(2);
    v.push_back(3);
    v.push_back(4);
    v.insert(v.begin(), 0); //在容器开头插入0

    v.insert(v.begin(), 5, -1); //在容器开头插入5个-1

    v.erase(v.begin()); //删除容器中的第一个元素

    v.erase(v.begin(), v.begin() + 5); //删除在该迭代器区间内的元素(左闭右开)

    return 0;
}

find函数:
find函数共三个参数,前两个参数确定一个迭代器区间(左闭右开),第三个参数确定所要寻找的值。
find函数在所给迭代器区间寻找第一个匹配的元素,并返回它的迭代器,若未找到,则返回所给的第二个参数。

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main()
{
    vector<int> v;
    v.push_back(1);
    v.push_back(2);
    v.push_back(3);
    v.push_back(4);
    vector<int>::iterator pos = find(v.begin(), v.end(), 2); //获取值为2的元素的迭代器

    v.insert(pos, 10); //在2的位置插入10

    pos = find(v.begin(), v.end(), 3); //获取值为3的元素的迭代器

    v.erase(pos); //删除3

    return 0;
}

注意: find函数是在算法模块(algorithm)当中实现的,不是vector的成员函数。

在这里再给大家介绍一个典型题

代码:

#include<iostream>
#include<string.h>
using namespace std;
int main()
{

    string s1, s2;
    cin >> s1 >> s2;
    if (s2.find(s1) != -1)//如果找到返回首位置,未找到返回-1
    {
        cout << s1 << " is substring of " << s2 << endl;
    }
    else if (s1.find(s2) != -1)
    {
        cout << s2 << " is substring of " << s1 << endl;
    }
    else
        cout << "No substring" << endl;
    return 0;
}

swap

通过swap函数可以交换两个容器的数据空间,实现两个容器的交换。

#include <iostream>
#include <vector>
using namespace std;

int main()
{
    vector<int> v1(10, 1);
    vector<int> v2(10, 2);

    v1.swap(v2); //交换v1,v2的数据空间

    return 0;
}

在c语言中交换两个数我们需要设立中间变量,而在c++中可以直接通过swap函数来解决

#include <iostream>
#include <vector>
using namespace std;

int main()
{
    vector<int> v1(10, 1);
    vector<int> v2(10, 2);

    v1.swap(v2); //交换v1,v2的数据空间

    return 0;
}

clear

清除字符串内容

#include"vector.h"
#include<iostream>
#include<vector>
using namespace std;



int main()
{
    //dabai::test1();
    vector<int> arr;
    vector<int> s;
    arr.push_back(11);
    arr.push_back(11);
    arr.push_back(11);
    arr.push_back(11);
    arr.pop_back();
    arr.insert(arr.begin()+2, 30);
    arr.erase(arr.begin() + 2);
    //arr.resize(2);
    //arr.reserve(100);
    s.swap(arr);
    cout << arr.size()<< endl;
    cout << s.size() << endl;
    s.clear();
    cout << s.size() << endl;
    return 0;
}

其实也相当于 s=““;

元素访问

vector当中实现了 [ ] 操作符的重载,因此我们也可以通过"下标+[ ]“的方式对容器当中的元素进行访问。

即你可以把他当作数组一样使用

#include <iostream>
#include <vector>
using namespace std;

int main()
{
    vector<int> v(10, 1);
    //使用"下标+[]"的方式遍历容器
    for (size_t i = 0; i < v.size(); i++)
    {
        cout << v[i] << " ";
    }
    cout << endl;
    return 0;
}

我们上面说到vector是支持迭代器的,所以我们还可以用范围for对vector容器进行遍历。(支持迭代器就支持范围for,因为在编译时编译器会自动将范围for替换为迭代器的形式)

#include <iostream>
#include <vector>
using namespace std;

int main()
{
    vector<int> v(10, 1);
    //范围for
    for (auto e : v)
    {
        cout << e << " ";
    }
    cout << endl;
    return 0;
}

原文链接: https://blog.csdn.net/2302_80084329/article/details/134902756

标签: #软件开发 1171
相关文章

万字:支付“核心系统”详解 2024-11-02 15:33

专栏作者:隐墨星辰 \| 主编:陈天宇宙 这篇文章也尝试化繁为简,探寻支付系统的本质,讲清楚在线支付系统最核心的一些概念和设计理念。 虽然支付行业已经过了风头最劲的时光,但跨境支付仍然在蓬勃发展,每年依然有很多新人进入这个行业,这篇文章尝试为这些刚入行的新人提供一点帮助。 文章只介绍一些支付行业十几

资深支付架构师视角:实战从问题定义到代码落地的完整套路 2024-11-02 15:33

前言 今天从一个实际案例入手,介绍站在架构师的角度,如何识别并定义问题,提炼需求,技术方案选型,再到详细设计,最后利用AI的能力协助写出核心的代码,验证与调优。 解决问题存在一定的模式,也可以称之为框架,总结出自己的思考和解题框架,以后再碰到同类型的问题就可以如庖丁解牛一样容易。 很多年前,我写代码

Spring 实现 3 种异步接口 2024-10-18 09:07

大家好,我是苏三~ 如何处理比较耗时的接口? 这题我熟,直接上异步接口,使用 Callable、WebAsyncTask 和 DeferredResult、CompletableFuture等均可实现。 但这些方法有局限性,处理结果仅返回单个值。在某些场景下,如果需要接口异步处理的同时,还持续不断地

重学SpringBoot3-集成Redis(五)之布隆过滤器 2024-10-08 11:24

更多SpringBoot3内容请关注我的专栏:《SpringBoot3》 期待您的点赞👍收藏⭐评论✍ 重学SpringBoot3-集成Redis(五)之布隆过滤器 1. 什么是布隆过滤器? * 基本概念 适用场景 2. 使用 Redis 实现布隆过滤器 * 项目依赖 Redis 配置

设计模式第16讲——迭代器模式(Iterator) 2024-10-08 11:24

一、什么是迭代器模式 迭代器模式是一种行为型设计模式,它提供了一种统一的方式来访问集合对象中的元素,而不是暴露集合内部的表示方式。简单地说,就是将遍历集合的责任封装到一个单独的对象中,我们可以按照特定的方式访问集合中的元素。 二、角色组成 抽象迭代器(Iterator):定义了遍历聚合对象所需的方法

vue2路由和vue3路由区别及原理 2024-10-08 11:24

一、Vue2 与 Vue3 路由的区别 1. 创建路由实例方式的不同 Vue 2 中,通过 Vue.use() 注册路由插件,并通过 new VueRouter() 来创建路由实例。 import Vue from 'vue';import VueRouter from 'vue-router';i

目录

IT 外包服务商

  • 意见投递
  • zyf6619

软件开发应用

主菜单

  • 首页
  • 软件开发
  • 计算机基础
  • Hello Halo
  • 新手必读
  • 关于本知识库
Copyright © 2024 your company All Rights Reserved. Powered by Halo.