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

2023-12-10 06:36

本文主要是介绍C++STL详解+代码分析+典例讲解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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; //10cout << v.capacity() << endl; //10v.reserve(20); //改变容器的capacity为20,size不变cout << v.size() << endl; //10cout << v.capacity() << endl; //20v.resize(15); //改变容器的size为15cout << v.size() << endl; //15cout << v.capacity() << endl; //20return 0;
}

empty

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

#include <iostream>
#include <vector>
using namespace std;int main()
{vector<int> v(10, 2);cout << v.empty() << endl;return 0;
}

vector的迭代器使用

 

7a77ac3e3e1f47998aa42b93947c2af5.png

 

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;
}

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

df7e3d7c4879424ca3b8a7dc5569d9f4.png

6cd7bb8c3dbe40dd821e0de1a7093768.png

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); //尾插元素1v.push_back(2); //尾插元素2v.push_back(3); //尾插元素3v.push_back(4); //尾插元素4v.pop_back(); //尾删元素v.pop_back(); //尾删元素v.pop_back(); //尾删元素v.pop_back(); //尾删元素return 0;
}

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

704f114e59a4428e8ebcda0016b5df02.png

 

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

#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;}elsecout << "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); //在容器开头插入0v.insert(v.begin(), 5, -1); //在容器开头插入5个-1v.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的位置插入10pos = find(v.begin(), v.end(), 3); //获取值为3的元素的迭代器v.erase(pos); //删除3return 0;
}

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

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

5e9f001e821442bca7c5758431652da1.png

代码:

#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;}elsecout << "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);//范围forfor (auto e : v){cout << e << " ";}cout << endl;return 0;
}

 

 

 

这篇关于C++STL详解+代码分析+典例讲解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/476287

相关文章

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

【C++ Primer Plus习题】13.4

大家好,这里是国中之林! ❥前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。有兴趣的可以点点进去看看← 问题: 解答: main.cpp #include <iostream>#include "port.h"int main() {Port p1;Port p2("Abc", "Bcc", 30);std::cout <<

性能分析之MySQL索引实战案例

文章目录 一、前言二、准备三、MySQL索引优化四、MySQL 索引知识回顾五、总结 一、前言 在上一讲性能工具之 JProfiler 简单登录案例分析实战中已经发现SQL没有建立索引问题,本文将一起从代码层去分析为什么没有建立索引? 开源ERP项目地址:https://gitee.com/jishenghua/JSH_ERP 二、准备 打开IDEA找到登录请求资源路径位置

C++包装器

包装器 在 C++ 中,“包装器”通常指的是一种设计模式或编程技巧,用于封装其他代码或对象,使其更易于使用、管理或扩展。包装器的概念在编程中非常普遍,可以用于函数、类、库等多个方面。下面是几个常见的 “包装器” 类型: 1. 函数包装器 函数包装器用于封装一个或多个函数,使其接口更统一或更便于调用。例如,std::function 是一个通用的函数包装器,它可以存储任意可调用对象(函数、函数

OpenHarmony鸿蒙开发( Beta5.0)无感配网详解

1、简介 无感配网是指在设备联网过程中无需输入热点相关账号信息,即可快速实现设备配网,是一种兼顾高效性、可靠性和安全性的配网方式。 2、配网原理 2.1 通信原理 手机和智能设备之间的信息传递,利用特有的NAN协议实现。利用手机和智能设备之间的WiFi 感知订阅、发布能力,实现了数字管家应用和设备之间的发现。在完成设备间的认证和响应后,即可发送相关配网数据。同时还支持与常规Sof

C++11第三弹:lambda表达式 | 新的类功能 | 模板的可变参数

🌈个人主页: 南桥几晴秋 🌈C++专栏: 南桥谈C++ 🌈C语言专栏: C语言学习系列 🌈Linux学习专栏: 南桥谈Linux 🌈数据结构学习专栏: 数据结构杂谈 🌈数据库学习专栏: 南桥谈MySQL 🌈Qt学习专栏: 南桥谈Qt 🌈菜鸡代码练习: 练习随想记录 🌈git学习: 南桥谈Git 🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈�

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

活用c4d官方开发文档查询代码

当你问AI助手比如豆包,如何用python禁止掉xpresso标签时候,它会提示到 这时候要用到两个东西。https://developers.maxon.net/论坛搜索和开发文档 比如这里我就在官方找到正确的id描述 然后我就把参数标签换过来

06 C++Lambda表达式

lambda表达式的定义 没有显式模版形参的lambda表达式 [捕获] 前属性 (形参列表) 说明符 异常 后属性 尾随类型 约束 {函数体} 有显式模版形参的lambda表达式 [捕获] <模版形参> 模版约束 前属性 (形参列表) 说明符 异常 后属性 尾随类型 约束 {函数体} 含义 捕获:包含零个或者多个捕获符的逗号分隔列表 模板形参:用于泛型lambda提供个模板形参的名

poj 1258 Agri-Net(最小生成树模板代码)

感觉用这题来当模板更适合。 题意就是给你邻接矩阵求最小生成树啦。~ prim代码:效率很高。172k...0ms。 #include<stdio.h>#include<algorithm>using namespace std;const int MaxN = 101;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int n