c++领域展开第十六幕——STL(vector容器的了解以及各种函数的使用)超详细!!!!

c++领域展开第十六幕——STL(vector容器的了解以及各种函数的使用)超详细!!!!
在这里插入图片描述

文章目录

前言

在c++专栏的上一篇博客我们详细讲解了string类的模拟实现
同时在模拟实现过程中也学会了很多
stl的学习就是:能用,明理,能扩展
今天我们来了解 stl 的另外一个容器——vector
fellow me

一、vector的介绍和使用

1.1 vector的介绍

vector
文档链接如上

在这里插入图片描述


文档里面详细介绍了vector
vector有关的 成员函数以及功能都能找到

1.2 vector的使用

学习vector的时候可以多翻翻文档,便于更好的理解

1.2.1 vector的定义

constructor——————构造函数声明接口说明
vector()(重点)————无参构造
vector(size_type n, const value_type& val =value_type())————构造并初始化n个val
vector (const vector& x); (重点) ————————拷贝构造
vector (InputIterator first, InputIterator last);———— 使用迭代器进行初始化构造

代码展示:

 vector<int> first;// 无参构造 vector<int>second(4,100);// 构造并初始化 4 个 val vector<int>third(second.begin(), second.end());// 使用迭代器进行初始化构造 vector<int>fourth(third);// 拷贝构造

1.2.2 vector iterator 的使用

iterator的使用————接口说明
begin + end(重点)
获取第一个数据位置的iterator/const_iterator, 获取最后一个数据的下一个位置的iterator/const_iterator
rbegin + rend
获取最后一个数据位置的reverse_iterator,获取第一个数据前一个位置的reverse_iterator

在这里插入图片描述


在这里插入图片描述


代码展示:

voidPrintVector(const vector<int>& v){// const对象使用const迭代器进行遍历打印 vector<int>::const_iterator it = v.begin();while(it != v.end()){ cout <<*it <<" ";++it;} cout << endl;}
// 使用push_back插入4个数据 vector<int> v; v.push_back(1); v.push_back(2); v.push_back(3); v.push_back(4);// 使用迭代器进行遍历打印 vector<int>::iterator it = v.begin();while(it != v.end()){ cout <<*it <<" ";++it;} cout << endl;// 使用迭代器进行修改 it = v.begin();while(it != v.end()){*it *=2;++it;}// 使用反向迭代器进行遍历再打印// vector<int>::reverse_iterator rit = v.rbegin();auto rit = v.rbegin();while(rit != v.rend()){ cout <<*rit <<" ";++rit;} cout << endl;

1.2.3 vector的空间增长问题

容量空间————接口说明
size ————————获取数据个数
capacity ——————获取容量大小
empty ———————判断是否为空
resize(重点) ———改变vector的size
reserve (重点) ——改变vector的capacity

  1. capacity的代码在vs和g++下分别运行会发现,vs下capacity是按1.5倍增长的,g++是按2倍增长的。这个问题经常会考察,不要固化的认为,vector增容都是2倍,具体增长多少是根据具体的需求定义的。vs是PJ版本STL,g++是SGI版本STL。
  2. reserve只负责开辟空间,如果确定知道需要用多少空间,reserve可以缓解vector增容的代价缺陷问题。
  3. resize在开空间的同时还会进行初始化,影响size。

代码展示:

// 可以试着运行下面代码// reisze(size_t n, const T& data = T())// 将有效元素个数设置为n个,如果时增多时,增多的元素使用data进行填充// 注意:resize在增多元素个数时可能会扩容voidTestVector1(){ vector<int> v;// set some initial content:for(int i =1; i <10; i++) v.push_back(i); v.resize(5); v.resize(8,100); v.resize(12);for(size_t i =0; i < v.size(); i++) cout <<' '<< v[i]; cout <<'\n';}// 测试vector的默认扩容机制// vs:按照1.5倍方式扩容// linux:按照2倍方式扩容voidTestVectorExpand(){ size_t sz; vector<int> v; sz = v.capacity();for(int i =0; i <100;++i){ v.push_back(i);if(sz != v.capacity()){ sz = v.capacity(); cout<< sz <<'\n';}}}// 往vecotr中插入元素时,如果大概已经知道要存放多少个元素// 可以通过reserve方法提前将容量设置好,避免边插入边扩容效率低voidTestVectorExpandOP(){ vector<int> v; size_t sz = v.capacity(); v.reserve(100);// 提前将容量设置好,可以避免一遍插入一遍扩容for(int i =0; i <100;++i){ v.push_back(i);if(sz != v.capacity()){ sz = v.capacity(); cout << sz <<'\n';}}}

1.2.4 vector的增删改查

vector增删查改—————— 接口说明
push_back(重点) ————尾插
pop_back (重点) ———— 尾删
insert —————————— 在position之前插入val
erase ——————————删除position位置的数据
swap ——————————交换两个vector的数据空间
operator[] (重点) ————像数组一样访问

// 尾插和尾删:push_back/pop_backvoidTestVector4(){ vector<int> v; v.push_back(1); v.push_back(2); v.push_back(3); v.push_back(4);auto it = v.begin();while(it != v.end()){ cout <<*it <<" ";++it;} cout << endl; v.pop_back(); v.pop_back(); it = v.begin();while(it != v.end()){ cout <<*it <<" ";++it;} cout << endl;}// 任意位置插入:insert和erase,以及查找find// 注意find不是vector自身提供的方法,是STL提供的算法voidTestVector5(){// 使用列表方式初始化,C++11新语法 vector<int> v{1,2,3,4};// 在指定位置前插入值为val的元素,比如:3之前插入30,如果没有则不插入// 1. 先使用find查找3所在位置// 注意:vector没有提供find方法,如果要查找只能使用STL提供的全局findauto pos =find(v.begin(), v.end(),3);if(pos != v.end()){// 2. 在pos位置之前插入30 v.insert(pos,30);} vector<int>::iterator it = v.begin();while(it != v.end()){ cout <<*it <<" ";++it;} cout << endl; pos =find(v.begin(), v.end(),3);// 删除pos位置的数据 v.erase(pos); it = v.begin();while(it != v.end()){ cout <<*it <<" ";++it;} cout << endl;}// operator[]+index 和 C++11中vector的新式for+auto的遍历// vector使用这两种遍历方式是比较便捷的。voidTestVector6(){ vector<int> v{1,2,3,4};// 通过[]读写第0个位置。 v[0]=10; cout << v[0]<< endl;// 1. 使用for+[]小标方式遍历for(size_t i =0; i < v.size();++i) cout << v[i]<<" "; cout << endl; vector<int> swapv; swapv.swap(v);// vector 的 swap使用 cout <<"v data:";for(size_t i =0; i < v.size();++i) cout << v[i]<<" "; cout << endl;// 2. 使用迭代器遍历 cout <<"swapv data:";auto it = swapv.begin();while(it != swapv.end()){ cout <<*it <<" ";++it;}// 3. 使用范围for遍历for(auto x : v) cout << x <<" "; cout << endl;}

二、vector在 oj 中的使用

只出现一次的数

只出现一次的数 I

在这里插入图片描述


还是比较简单的,就是按位异或就行,重复的元素按位异或之后就变成 0 了,只剩下出现一次的元素

classSolution{public:intsingleNumber(vector<int>& nums){int value =0;for(auto e : nums){ value ^= e;}return value;}};

删除有序数组中的重复项

删除有序数组中的重复项

在这里插入图片描述


还是比较简单的,双指针完美解决,不知道的可以去我的——code ability 专栏看看

classSolution{public:intremoveDuplicates(vector<int>& nums)//前后指针{int n = nums.size();int left =0;for(int right =1; right < n; right++){if(nums[right]!= nums[left]){if(right ==++left)continue;else{ nums[left]= nums[right];}}}return left+1;}};

杨辉三角

杨辉三角

在这里插入图片描述


这里有个实时扩容的问题, 因为杨辉三角每一行的个数都不一样
其他的处理就比较简单了,话不多说,看代码

classSolution{public: vector<vector<int>>generate(int numRows){ vector<vector<int>>vv(numRows);for(int i =0; i < numRows; i++){ vv[i].resize(i +1,1);}for(int i =2; i < vv.size(); i++){for(int j =1; j < vv[i].size()-1; j++){ vv[i][j]= vv[i -1][j]+ vv[i -1][j -1];}}return vv;}};

其实写了几道题目下来,vector和数组的用法其实差不多,但是vector还是会好一些
毕竟有了封装,使得很多东西都标准化,同时作为容器,在后面学习配接器的时候还是很爽的

总结

今天认识了vector以及vector的使用,学习vector的第一步算是到这里啦
下一篇博客就是来深究探讨vector,自己模拟实现一遍
不要走开,小编持续更新中~~~~

在这里插入图片描述

Read more

内网安全部署:Java + OpenClaw 本地大模型私有化方案

内网安全部署:Java + OpenClaw 本地大模型私有化方案

文章目录 * 前言 * 一、开篇:你的数据正在裸奔吗? * 二、技术栈选型:为什么选这三兄弟? * 2.1 本地大模型:Ollama是傻瓜相机 * 2.2 OpenClaw:AI界的机械臂 * 2.3 Java:老当益壮的底盘 * 三、架构设计:三层铁桶怎么搭? * 3.1 数据流向图(脑补版) * 3.2 安全边界划分 * 四、环境搭建:从0到1手摸手 * 4.1 本地模型部署(Ollama) * 4.2 OpenClaw安装与配置 * 4.3 Java项目准备 * 五、Java集成实战:代码说话 * 5.1 基础对话接口 * 5.

By Ne0inhk
【Java 学习】详讲 局部变量、成员变量

【Java 学习】详讲 局部变量、成员变量

1. 什么是成员变量?什么是局部变量? 局部变量和成员变量是两种常见的变量类型,它们在作用域、生命周期、初始化等方面有显著的区别。理解这两者的区别对于编写清晰和高效的 Java 程序至关重要。 创建一个类,在类中创建成员变量,然后创建对象,打印出对象的成员变量: publicclassPhone{String brand;// 品牌String color ;// 颜色int memory;// 内存// 程序的开始publicstaticvoidmain(String[] args){Phone p =newPhone();System.out.println("brand:"+ p.brand);System.out.println("color:"+p.color);System.out.println("memory:"

By Ne0inhk
飞算 JavaAI 进阶实战:从代码生成到系统架构优化的全流程指南

飞算 JavaAI 进阶实战:从代码生成到系统架构优化的全流程指南

飞算 JavaAI 进阶实战:从代码生成到系统架构优化的全流程指南 在 Java 开发领域,开发者常常面临三重困境:重复性劳动消耗大量时间(如 CRUD 代码编写)、 legacy 代码维护成本高昂(“祖传代码” 难以理解)、新技术探索门槛高(框架迭代快,学习成本大)。飞算 JavaAI 作为专注于 Java 领域的智能开发助手,通过深度理解业务需求与技术栈特性,将这些痛点转化为开发效率的增长点。 前言 文章前两篇,从第一篇《飞算JavaAI:精准切中开发者痛点,专治“AI生成代码不可用、逻辑混乱”的顽疾》 到 第二篇《飞算 JavaAI:让 Java 开发效率飙升的智能助手,日常开发全场景应用指南》,带大家了解了飞算JavaAI插件的实际应用,这篇文章将在第一篇的基础上,更加详细的聊聊它! 在 Java 开发领域,开发者常常面临三重困境:

By Ne0inhk
Java SpringBoot+Vue3+MyBatis 宠物领养系统系统源码|前后端分离+MySQL数据库

Java SpringBoot+Vue3+MyBatis 宠物领养系统系统源码|前后端分离+MySQL数据库

摘要 随着社会经济的快速发展和人们生活水平的提高,宠物已成为许多家庭的重要成员。然而,流浪动物问题日益严重,传统的线下领养模式存在信息不对称、流程繁琐等问题。为解决这一问题,开发一套高效、便捷的宠物领养系统具有重要意义。该系统通过互联网技术整合宠物信息、领养申请和用户管理功能,为领养者和救助机构搭建沟通桥梁,提升领养效率。关键词:宠物领养、流浪动物、互联网技术、信息整合、领养效率。 本系统基于Java SpringBoot框架搭建后端服务,采用Vue3实现前端交互,结合MyBatis完成数据持久化操作,MySQL数据库存储系统数据。系统功能涵盖用户注册登录、宠物信息管理、领养申请处理、数据统计分析等模块。前后端分离的设计模式提升了系统的可维护性和扩展性,RESTful API接口规范确保数据传输的高效性。系统通过权限控制和数据加密保障用户信息安全,同时支持多条件查询和分页展示优化用户体验。关键词:SpringBoot、Vue3、MyBatis、MySQL、前后端分离、权限控制。 数据表设计 用户信息数据表 用户信息数据表存储系统注册用户的个人资料,注册时间通过函数自动生成,用

By Ne0inhk