当前位置: 首页 > news >正文

【C++初阶】vector容器

在这里插入图片描述

👦个人主页:@Weraphael
✍🏻作者简介:目前学习C++和算法
✈️专栏:C++航路
🐋 希望大家多多支持,咱一起进步!😁
如果文章对你有帮助的话
欢迎 评论💬 点赞👍🏻 收藏 📂 加关注✨


目录

  • 一、什么是vector
  • 二、vector初始化
      • 2.1 默认构造函数(常见)
      • 2.2 构造函数将n个元素拷贝给本身
      • 2.3 拷贝构造函数(常见)
      • 2.4 区间拷贝
      • 2.5 数组方式
  • 三、迭代器的使用
      • 3.1 begin + end(常见)
      • 3.2 rbegin + rend
  • 四、遍历
      • 4.1 operator[]
      • 4.2 迭代器遍历
      • 4.3 范围for
  • 五、空间增长问题
      • 5.1 size
      • 5.2 empty
      • 5.3 resize
      • 5.4 reserve
      • 5.5 swap
  • 六、vector的插入与删除
      • 6.1 push_back - 尾插
      • 6.2 pop_back - 尾删
      • 6.3 insert - 插入
      • 6.4 erase - 删除pos位置的数据
      • 6.5 clear - 清空所有数据
  • 七、几个常用算法
      • 7.1 sort - 排序
      • 7.2 reverse
      • 7.3 find
  • 八、迭代器失效问题
      • 8.1 什么是迭代器失效
      • 8.2 为什么string不存在迭代器失效问题
      • 8.3 几个常见的迭代器失效样例
      • 8.4 如何解决迭代器失效问题

一、什么是vector

  • vector容器和数组非常相似,与普通数组的区别:数组是静态空间,而vector可以动态扩展
  • 动态扩展并不是在原空间之后续接新空间,而是找更大的内存空间,然后将原数据拷贝新空间,释放原空间
  • 使用vector容器需要包含头文件:#include <vector>
  • vector可以存储多种不同的数据类型,是因为它是一个模板容器
    在这里插入图片描述
    通过使用模板参数,我们可以在vector中指定要存储的数据类型,例如:
vector<int> vi // 整型容器
vector<char> vc // 字符型容器
vector<double> vd // 浮点型容器
vector<string> vs // string类型容器
vector<vector<int>> // 本质是二维数组
// 等等...

类模板实例化与普通类的实例化不同,类模板实例化需要在类模板名字后跟<>,然后将实例化的类型放在<>中即可,而普通类的类名就是类型。

注意:需要注意数据类型的统一性。例如,如果创建了一个存储整数的vector,就应该只向其中存储整数类型的数据,否则可能会出现类型错误或数据损坏的问题。

二、vector初始化

2.1 默认构造函数(常见)

#include <iostream>
#include <vector>
using namespace std;
int main()
{// 默认构造函数vector<int> v;return 0;
}

默认构造的对象,sizecapacity都为0。

在这里插入图片描述

2.2 构造函数将n个元素拷贝给本身

【函数原型】

vector<T> v(n,elem);

【代码示例】

#include <iostream>
#include <vector>
using namespace std;int main()
{// 构造函数将n个元素拷贝给本身// 将3个100拷贝给本身vector<int> v(3, 100);for (int i = 0; i < v.size(); i++){cout << v[i] << ' ';}cout << endl;return 0;
}

【输出结果】

在这里插入图片描述

2.3 拷贝构造函数(常见)

【函数原型】

vector (const vector& x);

【代码示例】

#include <iostream>
#include <vector>
using namespace std;int main()
{// 构造函数将3个100拷贝给本身vector<int> v1(3, 100);cout << "v1:";for (int i = 0; i < v1.size(); i++){cout << v1[i] << ' ';}cout << endl;// 拷贝构造函数// v2是v1的副本vector<int> v2(v1);cout << "v2:";for (int i = 0; i < v2.size(); i++){cout << v2[i] << ' ';}cout << endl;return 0;
}

【输出结果】

在这里插入图片描述

2.4 区间拷贝

【函数原型】

vector(v.begin(),v.end());

【代码示例】

#include <iostream>
#include <vector>
using namespace std;int main()
{// 构造函数将n个元素拷贝给本身// 将5个100拷贝给本身vector<int> v1;// 写入1 2 3 4 5v1.push_back(1);v1.push_back(2);v1.push_back(3);v1.push_back(4);v1.push_back(5);// 区间拷贝// 拷贝v1对象中的2、3、4、5vector<int> v2(v1.begin() + 1, v1.end());cout << "v2:";for (int i = 0; i < v2.size(); i++){cout << v2[i] << ' ';}cout << endl;return 0;
}

【输出结果】

在这里插入图片描述

2.5 数组方式

#include <iostream>
#include <vector>
#include <string>
using namespace std;int main()
{vector<int> v1{ 1,2,3,4,5,6 };vector<char> v2{ 'h','e','l','l','o' };vector<string> v3{ "hello", "vector" };return 0;
}

【输出结果】

在这里插入图片描述

三、迭代器的使用

3.1 begin + end(常见)

大家可以认为迭代器是指针。begin指向第一个数据的位置,end指向最后一个数据的下一个位置

在这里插入图片描述

【代码示例】

#include <iostream>
#include <vector>
using namespace std;int main()
{vector<char> v;// 插入abcdefgv.push_back('a');v.push_back('b');v.push_back('c');v.push_back('d');v.push_back('e');v.push_back('f');v.push_back('g');vector<char>::iterator begin = v.begin();// begin指向第一个元素,对齐解引用就能得到cout << "第一个元素为:" << *begin << endl;vector<char>::iterator end = v.end();// end指向最后一个元素的下一个位置cout << "最后一个元素为:" << *(end - 1) << endl;return 0;
}

【输出结果】

在这里插入图片描述

3.2 rbegin + rend

rbeginrend是反着来的。rbegin指向的是最后一个元素,rend指向的是第一个元素的前一个位置
在这里插入图片描述

【代码示例】

#include <iostream>
#include <vector>
using namespace std;int main()
{vector<char> v;// 插入abcdefgv.push_back('a');v.push_back('b');v.push_back('c');v.push_back('d');v.push_back('e');v.push_back('f');v.push_back('g');// vector<char>::iterator 如果认为太长// 可用autoauto vci = v.rbegin();// vci指向最后一个元素cout << "最后一个元素:" << *vci << endl;auto vcc = v.rend();// vcc指向第一个元素的前一个位置// 对其-1。就指向第一个元素cout << "第一个元素" << *(vcc - 1) << endl;return 0;
}

【输出结果】

在这里插入图片描述

四、遍历

4.1 operator[]

在这里插入图片描述

vector底层重载了下标访问操作符[],因此可以像数组一样变量

#include <iostream>
#include <vector>
using namespace std;
int main()
{vector<char> v;// 插入abcdefgv.push_back('a');v.push_back('b');v.push_back('c');v.push_back('d');v.push_back('e');v.push_back('f');v.push_back('g');// operator[]for (int i = 0; i < v.size(); i++){cout << v[i] << ' ';}cout << endl;return 0;
}

【输出结果】

在这里插入图片描述

4.2 迭代器遍历

#include <iostream>
#include <vector>
using namespace std;
int main()
{vector<char> v;// 插入abcdefgv.push_back('a');v.push_back('b');v.push_back('c');v.push_back('d');v.push_back('e');v.push_back('f');v.push_back('g');// 迭代器vector<char>::iterator begin = v.begin();while (begin != v.end()){cout << *begin << ' ';begin++;}cout << endl;// 以上用for循环也是可以的for (vector<char>::iterator begin = v.begin(); begin != v.end(); begin++){cout << *begin << ' ';}cout << endl;return 0;
}

【输出结果】

在这里插入图片描述

4.3 范围for

string类时,我们讲过 范围for的底层是迭代器。

#include <iostream>
#include <vector>
using namespace std;
int main()
{vector<char> v;// 插入abcdefgv.push_back('a');v.push_back('b');v.push_back('c');v.push_back('d');v.push_back('e');v.push_back('f');v.push_back('g');// 范围forfor (auto x : v){cout << x << ' ';}cout << endl;return 0;
}

【输出结果】

在这里插入图片描述

五、空间增长问题

5.1 size

功能:获取数据的有效个数

#include <iostream>
#include <vector>
using namespace std;int main()
{vector<int> v{ 1,2,3,4 };cout << "个数为:" << v.size() << endl;for (int i = 0; i < v.size(); i++){cout << v[i] << ' ';}cout << endl;return 0;
}

【输出结果】

在这里插入图片描述

5.2 empty

功能:判断容器是否为空。如果为空返回1,否则返回0

#include <iostream>
#include <vector>
using namespace std;int main()
{// 默认构造默认有效个数size为0vector<int> vi;cout << "vi:" << vi.empty() << endl;vector<char> vc{ 'h', 'e', 'l', 'l','o' };cout << "vc:" << vc.empty() << endl;return 0;
}

【输出结果】

在这里插入图片描述

5.3 resize

【函数原型1】

resize(int num);

功能:重新指定容器的长度为num

情况1:若有效数据size > num,则会保留前num个,剩下的删除

#include <iostream>
#include <vector>
using namespace std;int main()
{vector<int> v{ 1,2,3,4,5,6 };cout << "改变之前的长度:" << v.size() << endl;// 重新指定容器长度// 保留前3个v.resize(3);cout << "改变后的长度:" << v.size() << endl;cout << "改变后的内容为:";for (int i = 0; i < v.size(); i++){cout << v[i] << ' ';}cout << endl;return 0;
}

【程序结果】

在这里插入图片描述

【函数原型2】

resize(int num, elem);

情况2:若num > size,则会增加有效长度。如果不指定第二个参数,默认增加的内容是0

#include <iostream>
#include <vector>
using namespace std;int main()
{vector<int> v1{ 1,2,3,4 };v1.resize(6);// 增加了2个,不指定第二个参数默认是0for (auto x : v1){cout << x << ' ';}cout << endl;vector<char> v2{ 'h','i' };v2.resize(6, 'x');for (auto x : v2){cout << x << ' ';}cout << endl;return 0;
}

【输出结果】

在这里插入图片描述

5.4 reserve

功能:改变vector容器的容量。一般都是扩容。

#include <iostream>
#include <vector>
using namespace std;int main()
{vector<int> v;int capacity = v.capacity();for (int i = 0; i < 100; i++){// 插入100个数据v.push_back(i);// v.capacity是输出当前容量的if (capacity != v.capacity()){capacity = v.capacity();cout << "容量改变:" << capacity << '\n';}}return 0;
}

【输出结果】

在这里插入图片描述

通过以上代码我们发现:vs下的容量是按1.5倍增长的g++是按2倍增长的。

然后我们再把以上代码拿到Linux环境下测试:

在这里插入图片描述

我们发现:Linux下使用的vector是按照2倍方式扩容。

因此,如果已经确定vector中要存储元素大概个数,可以提前将空间设置足够就可以避免边插入边扩容导致效率低下的问题了。

#include <iostream>
#include <vector>
using namespace std;int main()
{vector<int> v;int capacity = v.capacity();// 提前开好大小为100的容量v.reserve(100);for (int i = 0; i < 100; i++){// 插入100个数据v.push_back(i);// v.capacity是输出当前容量的if (capacity != v.capacity()){capacity = v.capacity();cout << "容量改变:" << capacity << '\n';}}return 0;
}

【输出结果】

在这里插入图片描述

或者还能这样开空间:

在这里插入图片描述

5.5 swap

【函数原型】

swap(vec); // 将vec与本身的元素互换

【代码示例】

#include <iostream>
#include <vector>
using namespace std;int main()
{vector<int> v1{1,2,3,4,5,6};v1.reserve(100);cout << "交换前:" << endl;cout << "v1:";for (auto x : v1){cout << x << ' ';}cout << endl;vector<int> v2{ 7,8,9,10,11, 12 };cout << "v2:";for (auto x : v1){cout << x << ' ';}cout << endl;cout << "v1的容量" << v1.capacity() << endl;cout << "v2的容量" << v2.capacity() << endl;// 交换v1.swap(v2);cout << "交换后:" << endl;cout << "v1:";for (auto x : v1){cout << x << ' ';}cout << endl;cout << "v2:";for (auto x : v1){cout << x << ' ';}cout << endl;cout << "v1的容量" << v1.capacity() << endl;cout << "v2的容量" << v2.capacity() << endl;return 0;
}

【输出结果】

在这里插入图片描述

通过以上发现:swap不仅可以交换容器内容,同时还达到实用的收缩内存效果

六、vector的插入与删除

6.1 push_back - 尾插

#include <iostream>
#include <vector>
using namespace std;int main()
{vector<int> v;// 尾插1、2、3、4v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);for (auto x : v){cout << x << ' ';}cout << endl;return 0;
}

【输出结果】

在这里插入图片描述

6.2 pop_back - 尾删

#include <iostream>
#include <vector>
using namespace std;int main()
{vector<int> v;// 尾插1、2、3、4v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);for (auto x : v){cout << x << ' ';}cout << endl;// 删掉4v.pop_back();for (auto x : v){cout << x << ' ';}cout << endl;return 0;
}

【输出结果】

在这里插入图片描述

6.3 insert - 插入

【函数原型1】

iterator insert (iterator position, const value_type& val);

注意:insert是要配合迭代器使用的!

#include <iostream>
#include <vector>
using namespace std;int main()
{vector<int> v;// 尾插1、2、3、4v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);for (auto x : v){cout << x << ' ';}cout << endl;// 头插一个6v.insert(v.begin(), 6);for (auto x : v){cout << x << ' ';}cout << endl;return 0;
}

【输出结果】

在这里插入图片描述

【函数原型2】

void insert (iterator position, size_type n, const value_type& val);

【代码样例】

#include <iostream>
#include <vector>
using namespace std;int main()
{vector<int> v;// 尾插1、2、3、4v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);for (auto x : v){cout << x << ' ';}cout << endl;// 尾插4个6v.insert(v.end(), 4, 6);for (auto x : v){cout << x << ' ';}cout << endl;return 0;
}

【输出结果】

在这里插入图片描述

6.4 erase - 删除pos位置的数据

【函数原型1】

erase(const iterator pos);

注意: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.erase(v.end() - 1);for (auto x : v){cout << x << ' ';}cout << endl;return 0;
}

【输出结果】

在这里插入图片描述

【函数原型2】

erase(const iterator start,const iterator end)

功能:删除某个区间的数据

【代码示例】

#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.erase(v.begin(), v.end());for (auto x : v){cout << x << ' ';}cout << endl;return 0;
}

【输出结果】

在这里插入图片描述

除了以上方式可以清空数据,clear同样也行

6.5 clear - 清空所有数据

#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.clear();for (auto x : v){cout << x << ' ';}cout << endl;return 0;
}

【输出结果】

在这里插入图片描述

七、几个常用算法

注意:使用库里的算法需要加上头文件#include <algorithm>

7.1 sort - 排序

#include <iostream>
#include <vector>
using namespace std;
#include<algorithm>int main()
{vector<int> a{ 4,7,1,0,5,3, 2 };// 从小到大sort(a.begin(), a.end());for (auto x : a){cout << x << ' ';}cout << endl;// 从大到小sort(a.rbegin(), a.rend());for (auto x : a){cout << x << ' ';}cout << endl;return 0;
}

【输出结果】

在这里插入图片描述

7.2 reverse

#include <iostream>
#include <vector>
using namespace std;
#include<algorithm>int main()
{vector<int> a{ 1,2,3,4,5,6 };//逆置reversereverse(a.begin(), a.end());for (auto x : a){cout << x << ' ';}cout << endl;return 0;
}

【输出结果】

在这里插入图片描述

7.3 find

注意:vector是没有提供find接口的。而我们知道vector是一个类似于数组的容器,因此如果想找一个数据,直接遍历即可。但是算法库提供了find

#include <iostream>
#include <vector>
using namespace std;
#include<algorithm>int main()
{vector<int> a{ 1,2,3,4,5,6 };// 查找4vector<int>::iterator pos = find(a.begin(), a.end(), 4);if (pos != a.end()){// 找到4就删掉a.erase(pos);}for (auto x : a){cout << x << ' ';}cout << endl;return 0;
}

【输出结果】

在这里插入图片描述

八、迭代器失效问题

8.1 什么是迭代器失效

迭代器失效实际就是迭代器底层对应指针所指向的空间被销毁了,而使用一块已经被释放的空间,造成的后果是程序崩溃。即如果继续使用已经失效的迭代器,程序可能会崩溃。

8.2 为什么string不存在迭代器失效问题

string是一个特殊的容器,它是由字符组成的连续序列,类似于C语言的字符串。string类会动态地管理内部存储区域,确保足够的容量容纳字符串。当我们向string中插入或删除字符时,并不会导致整个字符串被复制到新的内存位置,因此迭代器不会失效。

对比vector,它是一个动态数组,它使用连续的内存存储元素。当我们向vector中插入元素时,如果导致当前内存不足以容纳所有元素,vector会重新分配更大的内存空间,并将所有元素复制到新的内存中。这样一来,原来指向旧内存中的元素的迭代器就会失效,因为它们指向的位置已经改变了。

8.3 几个常见的迭代器失效样例

当涉及到插入或删除操作时,我们需要注意vector迭代器的失效问题

  • 会引起其底层空间改变的操作,都有可能是迭代器失效,比如:resizereserveinsertpush_back
#include <iostream>
#include <vector>
using namespace std;int main()
{vector<int> v{ 1, 2, 3 };// 1. 将有效元素个数增加到100个//   多出的位置使用6填充,操作期间底层会扩容v.resize(100, 6);// 2. reserve的作用就是改变扩容大小但不改变有效元素个数,// 操作期间可能会引起底层容量改变v.reserve(100);// 3. insert和尾插期间// 可能会引起扩容,而导致原空间被释放v.insert(v.begin(), 0);v.push_back(10);return 0;
}

以上操作可能会导致vector扩容,扩容就会导致旧空间被释放掉,而返回的迭代器是指向被释放的空间,如果再对迭代器进行使用,会引起代码崩溃。

  • 指定位置元素的删除操作
#include <iostream>
#include <vector>
using namespace std;int main()
{int a[] = { 1, 2, 3, 4, 5 };vector<int> v(a, a + sizeof(a) / sizeof(int));// 使用find查找4所在位置auto pos = find(v.begin(), v.end(), 4);// 删除pos位置的数据,v.erase(pos);// 预测打印5cout << *pos << endl;return 0;
}

【输出结果】

理论上删除了4*pos应该是5,可是为什么没有打印出来呢?

我们可以通过调试来观察:

在这里插入图片描述

当我再按F10,发现pos的地址变了:

在这里插入图片描述

理论上删除4后,5应该占据4的空间,然而地址却变了。因此导致了迭代器失效了。

那如果是删除最后一个数据,那么结果更加明显:

在这里插入图片描述

8.4 如何解决迭代器失效问题

在使用前,对迭代器重新赋值即可。

#include <vector>
#include <iostream>
using namespace std;
int main()
{vector<int> v{ 1,2,3,4,5,6,7,8,9,10};// 保留1 2 3// 剩下全删除vector<int>::iterator it = v.begin() + 3;while (it != v.end()){// 在使用之前重新赋值it = v.erase(it);}for (auto& x : v){cout << x << ' ';}cout << endl;return 0;
}

在这里插入图片描述

【输出结果】

在这里插入图片描述

相关文章:

【C++初阶】vector容器

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前学习C和算法 ✈️专栏&#xff1a;C航路 &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章对你有帮助的话 欢迎 评论&#x1f4ac; 点赞&#x1…...

ThreadLocal深度解析

简介 在并发编程中&#xff0c;导致并发bug的问题都会归结于对共享变量的操作不当。多个线程同时读写同一共享变量存在并发问题&#xff0c;我们可以利用写时复制、不变性来突破对原数据的写操作&#xff0c;没有写就没有并发问题&#xff0c;而本篇文章所介绍的技术是突破共享…...

06有监督学习——迁移学习

1.迁移学习分类 &#xff08;1&#xff09; 基于实例的迁移学习方法&#xff1a; 假设:源域中的一些数据和目标域会共享很多共同的特征方法:对源域进行instance reweighting&#xff0c;筛选出与目标域数据相似度高的数据&#xff0c;然后进行训练学习 &#xff08;2&#x…...

快速连接服务器脚本 可从多个服务中选择并连接

使用 python 做一个可选择服务器登录连接的脚本 前置条件 需要有python 环境python --version 显示版本号即可检查 python 是否有 paramiko 包没有的话 python install paramiko创建一个python 文件,内容如下 # -*- coding: utf-8 -*-""" Authors: huxiaohua…...

MemSeg:一种差异和共性来检测图像表面缺陷的半监督方法

目录 1、摘要 2、Method 2.1 模拟异常样本 2.2 Memory Module 2.3 空间注意模块 2.4 多尺度特征融合模块 2.5 损失函数设置 2.6 Decoder模块 1、摘要 本文认为人为创建类内差异和保持类内共性可以帮助模型实现更好的缺陷检测能力&#xff0c;从而更好地区分非正常图像。如…...

迈向未来的大门:人脸识别技术的突破与应用

迈向未来的大门&#xff1a;人脸识别技术的突破与应用 人脸识别&#xff1a;人脸识别的工作流程人脸识别的作用人脸识别技术的突破与应用 在深度学习人脸识别之前我们要先知道人脸识别是什么。 人脸识别&#xff1a; 人脸识别是一种基于人脸图像或视频进行身份验证或识别的技术…...

Vue-9.集成(.editorconfig、.eslintrc.js、.prettierrc)

介绍 同时使用 .editorconfig、.prettierrc 和 .eslintrc.js 是很常见的做法&#xff0c;因为它们可以在不同层面上帮助确保代码的格式一致性和质量。这种组合可以在开发过程中提供全面的代码维护和质量保证。然而&#xff0c;这也可能增加一些复杂性&#xff0c;需要谨慎配置…...

Qt 编译使用Bit7z库接口调用7z.dll、7-Zip.dll解压压缩常用Zip、ISO9660、Wim、Esd、7z等格式文件(一)

bit7z一个c静态库&#xff0c;为7-zip共享库提供了一个干净简单的接口 使用CMAKE重新编译github上的bit7z库&#xff0c;用来解压/预览iso9660&#xff0c;WIm&#xff0c;Zip,Rar等常用的压缩文件格式。z-zip库支持大多数压缩文件格式 导读 编译bit7z(C版本)使用mscv 2017编译…...

AndroidUI体系

见&#xff1a;GitHub - eHackyd/Android_UI: Android UI体系的学习笔记...

CBV (基于类的视图)源码解析(1)

面向对象和反射的一些补充说明 class Animal:def __init__(self, name, age, func_str):self.name nameself.age age# self 指的是类实例对象&#xff0c;此处指的是 Dog 的实例对象# 所以如果 Dog 中重写了 sleep 方法&#xff0c;那么 self.sleep() 调用的就是 Dog 中的 s…...

2023-08-17 Untiy进阶 C#知识补充7——C#8主要功能与语法

文章目录 一、Using 声明二、静态本地函数三、Null 合并赋值四、解构函数 Deconstruct五、模式匹配增强功能 ​ 注意&#xff1a;在此仅提及 Unity 开发中会用到的一些功能和特性&#xff0c;对于不适合在 Unity 中使用的内容会忽略。 ​ C# 8 对应 Unity 版本&#xff1a; Un…...

登陆接口的的Filter过滤

目录 一、概述 二、基本操作 三、登陆检查接口 一、概述 什么是Filter&#xff1f; Filter表示过滤器&#xff0c;是 JavaWeb三大组件(Servlet、Filter、Listener)之一。 过滤器可以把对资源的请求拦截下来&#xff0c;从而实现一些特殊的功能 使用了过滤器之后&#xff0…...

【Python原创设计】基于Python Flask的全国气象数据采集及可视化系统-附下载方式以及项目参考论文,原创项目其他均为抄袭

基于Python Flask的全国气象数据采集及可视化系统 一、项目简介二、项目技术三、项目功能四、运行截图五、分类说明六、实现代码七、数据库结构八、源码下载 一、项目简介 本项目是一个基于Web技术的实时气象数据可视化系统。通过爬取中国天气网的各个城市气象数据&#xff0c…...

【力扣】42. 接雨水 <模拟、双指针、单调栈>

【力扣】42. 接雨水 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图&#xff0c;计算按此排列的柱子&#xff0c;下雨之后能接多少雨水。 目录 【力扣】42. 接雨水题解暴力双指针单调栈 示例 1&#xff1a; 输入&#xff1a;height [0,1,0,2,1,0,1,3,2,1,2,1] 输出&…...

【leetcode 力扣刷题】链表基础知识 基础操作

链表基础知识 基础操作 链表基础操作链表基础知识插入节点删除节点查找节点 707. 设计链表实现&#xff1a;单向链表&#xff1a;实现&#xff1a;双向链表 链表基础操作 链表基础知识 在数据结构的学习过程中&#xff0c;我们知道线性表【一种数据组织、在内存中存储的形式】…...

关于openfeign调用时content-type的问题

问题1描述&#xff1a; 今天在A服务使用openfeign调用B服务的时候&#xff0c;发现经常会偶发性报错。错误如下&#xff1a; 情况为偶发&#xff0c;很让人头疼。 两个接口如下&#xff1a; A服务接口&#xff1a; delayReasonApi.test(student);就是使用openfeign调用B服务的…...

OpenCV 玩转图像和视频

为什么学OpenCV&#xff1f; • OpenCV ⽀持对图像缩放、旋转、绘制⽂字图形等基础操作 • OpenCV 库包含了很多计算机视觉领域常⻅算法&#xff1a;⽬标检测、⽬标跟踪等 OpenCV 简介 • OpenCV (Open Source Computer Vision) 是计算机视觉和机器学习软件库 • Intel 1999…...

技术分享 | 如何编写同时兼容 Vue2 和 Vue3 的代码?

LigaAI 的评论编辑器、附件展示以及富文本编辑器都支持在 Vue2&#xff08;Web&#xff09;与 Vue3&#xff08;VSCode、lDEA&#xff09;中使用。这样不仅可以在不同 Vue 版本的工程中间共享代码&#xff0c;还能为后续升级 Vue3 减少一定阻碍。 那么&#xff0c;同时兼容 Vue…...

基于ArcGis提取道路中心线

基于ArcGis提取道路中心线 文章目录 基于ArcGis提取道路中心线前言一、生成缓冲区二、导出栅格数据三、导入栅格数据四、新建中心线要素五、生成中心线总结 前言 最近遇到一个问题&#xff0c;根据道路SHP数据生成模型的时候由于下载的道路数据杂项数据很多&#xff0c;所以导…...

xcode14.3更新一系列问题

1. Missing file libarclite_iphoneos.a (Xcode 14.3) 解决方法 Xcode升级到14.3后编译失败&#xff0c;完整错误日志&#xff1a; File not found: /Applications/Xcode-beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/arc/libarclite_iphoneo…...

1U和2U的服务器怎么选择

企业建设网站的过程中&#xff0c;离不开租用服务器的环节&#xff0c;服务器在多种场景里面都可以发挥作用&#xff0c;服务器租用渠道有哪些&#xff1f;1U、2U选哪种服务器比较好&#xff1f;大家跟着壹基比小鑫一起来了解具体内容吧&#xff01; 1U、2U选哪种服务器比较好&…...

【SA8295P 源码分析】05 - SA8295P QNX Host 上电开机过程 进一步梳理(结合代码)

【SA8295P 源码分析】05 - SA8295P QNX Host 上电开机过程 进一步梳理(结合代码) 一、APPS PBL(Application Primary Boot Loader):固化在CPU ROM中1.1 APPS PBL 加载 XBL Loader1.2 XBL Loader加载验证并运行SMSS进行自检,自检完成后触发Warm Reset1.3 WarmRest后,APPS…...

【数据结构与算法】迪杰斯特拉算法

迪杰斯特拉算法 介绍 迪杰斯特拉&#xff08;Dijkstra&#xff09;算法是典型最短路径算法&#xff0c;用于计算一个节点到其他节点的最短路径。它的主要特点是以中心向外层层扩展&#xff08;广度优先搜索思想&#xff09;&#xff0c;直到扩展到终点为止。 算法过程 设置…...

python爬虫-网页数据提取

import requests #headers 网页右键->Network->最下面的User-Agent复制。 headers {"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36"} #你想要的网址 url &q…...

ZigBee的Many-to-One和Source Routing

1. Many-to-One Routing Many-to-One Routing&#xff0c;是一种简单的路由机制&#xff0c;使得整个网络中的路由设备拥有回到中心节点的路由。 在这种机制下&#xff0c;中心节点周期性发送Many-to-One route discovery广播&#xff08;协议栈默认设置为60s&#xff0c;可以…...

七夕节 Chinese Valentine‘s Day 的由来

农历七月初七是七夕节。Qixi Festival falls on the seventh day of the seventh lunar month. 以前有一个牛郎&#xff0c;和他的哥哥和嫂子住在一起。他放的一头牛曾经是天庭的一个神仙&#xff0c;但他违反天庭的戒律&#xff0c;变成牛放到了人间。As the story goes,once …...

掌握JDK21全新结构化并发编程,轻松提升开发效率!

1 概要 通过引入结构化并发编程的API&#xff0c;简化并发编程。结构化并发将在不同线程中运行的相关任务组视为单个工作单元&#xff0c;从而简化错误处理和取消操作&#xff0c;提高可靠性&#xff0c;并增强可观察性。这是一个预览版的API。 2 历史 结构化并发是由JEP 42…...

【SA8295P 源码分析】00 - 系列文章链接汇总 - 持续更新中

【SA8295P 源码分析】00 - 系列文章链接汇总 - 持续更新中 一、分区、下载、GPIO等杂项相关二、开机启动流程代码分析二、OpenWFD 显示屏模块三、Touch Panel 触摸屏模块四、QUPv3 及 QNX Host透传配置五、Camera 摄像头模块&#xff08;当前正在更新中...&#xff09;六、网络…...

TCP拥塞控制详解 | 6. 主动队列管理

网络传输问题本质上是对网络资源的共享和复用问题&#xff0c;因此拥塞控制是网络工程领域的核心问题之一&#xff0c;并且随着互联网和数据中心流量的爆炸式增长&#xff0c;相关算法和机制出现了很多创新&#xff0c;本系列是免费电子书《TCP Congestion Control: A Systems …...

前端学习清单

顺序不分先后。 技术名称技术描述技术链接HTML5HTML5是下一代的HTML标准&#xff0c;是一种用于结构化内容的标记语言。MDN|HTMLCSS3CSS3是CSS技术的升级版本&#xff0c;它的最大好处就是可以让网页设计师更加方便的为网页添加各种各样的样式&#xff0c;而不用再局限于文字、…...

go atomic原子操作详细解读

文章目录 概要1、基本知识1.1 原子操作是什么1.2 CPU怎么实现原子操作的&#xff1f; 2、atomic包2.1、 Add函数2.2、CompareAndSwap函数2.3、Swap函数2.4、Load函数2.5、Store函数 3、atomic.Value值 概要 atomic包是golang通过对底层系统支持的原子操作进行封装&#xff0c;…...

Vue用JSEncrypt对长文本json加密以及发现解密失败

哈喽 大家好啊&#xff0c;最近发现进行加密后 超长文本后端解密失败&#xff0c;经过看其他博主修改 JSEncrypt原生代码如下&#xff1a; // 分段加密&#xff0c;支持中文JSEncrypt.prototype.encryptUnicodeLong function (string) {var k this.getKey();//根据key所能编…...

Excel/PowerPoint折线图从Y轴开始(两侧不留空隙)

默认Excel/PowerPoint折线图是这个样子的&#xff1a; 左右两侧都留了大块空白&#xff0c;很难看 解决方案 点击横坐标&#xff0c;双击&#xff0c;然后按下图顺序点击 效果...

C++的类成员对齐

这是个小语法点&#xff0c;之前我们的对齐方式都是使用#pragma pack&#xff0c;这个方式实际是依赖编译器&#xff0c;且粒度粗(如果#pragma pack(1)之后没有#pragma pack(),那就作用整个进程了)。在C11之后引入关键字alignas&#xff0c;以此来实现对齐更加便利&#xff0c;…...

敏感挂载userhelper容器逃逸复现

目录 前言 分析 实验 前言 分析 实验 # Creates a payload cat "#!/bin/sh" > /evil-helper cat "ps > /output" >> /evil-helper chmod x /evil-helper # Finds path of OverlayFS mount for container # Unless the configuration ex…...

深度解读Promise.prototype.finally

由一个问题引发的血案&#xff1a; 手写源码实现Promise.prototype.finally。 我们知道&#xff0c;对于promise来讲&#xff0c;当状态敲定&#xff0c;无论状态兑现或拒绝时都需要调用的函数&#xff0c;可以使用Promise.prototype.finally的回调来实现。那么如何手写实现Pro…...

如何实现24/7客户服务自动化?建设智能客服知识库

客户自助服务是指用户通过企业或者第三方建立的网络平台或者终端&#xff0c;实现相关的自定义处理。实现客户服务自动化&#xff0c;对提高客户满意度、维持客户关系至关重要。客户服务自动化可以帮助企业以更快的速度和更高的效率来满足客户的售后服务要求&#xff0c;以进一…...

和鲸 ModelWhale 与中科可控多款服务器完成适配认证,赋能中国云生态

当前世界正处于新一轮技术革命及传统产业数字化转型的关键期&#xff0c;云计算作为重要的技术底座&#xff0c;其产业发展与产业规模对我国数字经济的高质量运行有着不可取代的推动作用。而随着我国数字上云、企业上云加快进入常规化阶段&#xff0c;云计算承载的业务应用越来…...

selenium +Jmeter 的性能测试

通过Jmeter快速将已有的Selenium 代码以性能测试的方式组织起来&#xff0c;并使用JMeter 丰富的报表展示测试结果 from selenium import webdriver from selenium.webdriver.common.action_chains import ActionChains from selenium.webdriver.common.by import By driver …...

探索高效的HTTP异步接口测试方法:从轮询等待到自动化方案

本文将深入探讨HTTP异步接口测试的多个方面&#xff0c;包括轮询等待、性能测试以及自动化方案。通过详细的解释和实际案例&#xff0c;帮助您了解如何有效地测试异步接口&#xff0c;确保系统的稳定性和性能。 在现代软件开发中&#xff0c;HTTP异步接口扮演着至关重要的角色&…...

Android资深工程书之LiveData核心组件原理剖析

LiveData是Android架构组件库中的一个类&#xff0c;用于在应用程序组件之间共享数据。它是一种可观察的数据持有者&#xff0c;可以感知应用程序组件的生命周期&#xff0c;并在数据发生变化时通知观察者。 使用LiveData 在Android应用程序中使用LiveData&#xff0c;你可以…...

Vue的五种方法实现加减乘除运算

五种方法的详细说明&#xff1a; 计算属性&#xff08;Computed Properties&#xff09;&#xff1a; 计算属性是Vue.js提供的一种便捷的属性&#xff0c;它根据依赖的数据动态计算出一个新的值。计算属性的值会被缓存&#xff0c;只有当依赖的数据发生变化时&#xff0c;才会…...

C++(1)Linux基础知识

经济下行&#xff0c;计算机就业形势严峻&#xff0c;为了勉励自己继续进步&#xff0c;继续学习代码提高核心竞争力。 安装QT Creator 首先&#xff0c;安装QT开发工具QT Creator 参考&#xff1a;2021最新Qt6开发环境&#xff08;Qt Creator&#xff09;安装以及卸载记录_q…...

接口自动化yaml文件读取与写入

前言 在走进yaml文件之前大家应该都很想知道他是用来干嘛的&#xff1f; 是的是的&#xff0c;他是用来做接口自动化测试的。 我们一起来学习他吧&#xff01;——&#xff08;一定要收藏带走哦❤&#xff09; 1、yaml文件有什么作用呢&#xff1f; ①可作为配置文件使用—…...

Java Map、JSONObject、实体类互转

文章目录 前言Map、JSONObject、实体类互转 前言 使用库 com.alibaba.fastjson2&#xff0c;可完成大部分JSON转换操作。 详情参考文章: Java FASTJSON2 一个性能极致并且简单易用的JSON库 Map、JSONObject、实体类互转 import com.alibaba.fastjson2.JSON; import com.alib…...

在Hive/Spark上执行TPC-DS基准测试 (PARQUET格式)

在上一篇文章:《在Hive/Spark上运行执行TPC-DS基准测试 (ORC和TEXT格式)》中,我们介绍了如何使用 hive-testbench 在Hive/Spark上执行TPC-DS基准测试,同时也指出了该项目不支持parquet格式。 如果我们想要生成parquet格式的测试数据,就需要使用其他工具了。本文选择使用另…...

基于CentOS搭建私有仓库harbor

环境&#xff1a; 操作系统&#xff1a;CentOS Linux 7 (Core) 内核&#xff1a; Linux 3.10.0-1160.el7.x86_64 目录 安装搭建harbor &#xff08;1&#xff09;安装docker编排工具docker compose &#xff08;2&#xff09;下载Harbor 安装包 &#xff08;3&…...

PDF怎么转Word?8 个最佳 PDF 转 Word 转换器

PDF 转 Word 转换工具只是一个特殊程序&#xff0c;可以将 PDF&#xff08;本机和/或扫描&#xff09;转换为 Microsoft Office Word 格式。将 PDF 导出到 Word 的主要原因之一是满足可编辑文档的需求&#xff0c;尽管还有其他原因。 由于缺少 PDF 阅读器&#xff0c;您可以选…...

老板都爱看的财务数据分析报表,全在这了

老板们都爱看哪些财务数据分析报表&#xff1f;自然是可以帮助他们更好地了解公司的财务状况和经营绩效的那一类财务数据分析报表&#xff0c;比如利润表、资产负债表、现金流量表、应收账款分析报表、应付账款分析报表、库存分析报表等。奥威BI数据可视化工具有一套标准化财务…...

ZooKeeper(zk)与 Eureka 的区别及集群模式比较分析

​ 作者&#xff1a;zhaokk 推荐阅读 AI文本 OCR识别最佳实践 AI Gamma一键生成PPT工具直达链接 玩转cloud Studio 在线编码神器 玩转 GPU AI绘画、AI讲话、翻译,GPU点亮AI想象空间 资源分享 「java、python面试题」来自UC网盘app分享&#xff0c;打开手机app&#xff…...