当前位置: 首页 > 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;而不用再局限于文字、…...

html5网站建设方案/百度竞价推广怎么做

<script type"text/javascript">//正常版 // (function(){ // alert(好)//返回加 // })()(function(){alert(好好)}()); //正常版不能同时出现&#xff08;如果一起出现了下面也无法执行了&#xff0c;二者出现一个就可正常运行&#xff09;//特殊版 fu…...

猎头公司网站模板/晚上国网app

插入表格/列表/图片 新建桌面应用程序testRichText&#xff0c;基类QMainWindow,勾选创建界面文件&#xff0c;其他选择默认。编辑mainwindow.cpp构造函数 mainwindow.h #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> namespace Ui {class MainW…...

网站服务器自己做/南宁seo

启动 unity3d , 打开示例代码 file ---> build settings ... 对话框窗口。 scenes in build 中选择 car 的那个示例。 点击 build 按钮。 生成 *.apk 文件。 复制到安卓手机&#xff08;测试过小米4&#xff0c;三星 s7 edge&#xff09;上&#xff0c;并安装。 可以…...

开了外网网站打不开/百度网址大全下载安装

16/32位基本寄存器##段寄存器的使用指令指针寄存器和标志寄存器标志寄存器(FLAGS):用于存放系统的状态标志和控制标志。状态标志&#xff1a;是CPU在执行指令的过程中产生的。有的指令影响状态标志&#xff0c;有的不影响&#xff0c;还有的指令与当前状态标志有关。标志寄存器…...

网站建设设计书/大连seo按天付费

原文链接&#xff1a;http://docs.autofac.org/en/latest/lifetime/index.html Lifetime 是指服务的实例在程序中存活多久 – 从最初的实例化到清理&#xff08;disposal&#xff09;。例如&#xff0c;一个实现 IDisposable 的对象&#xff0c;它的生命周期就是从实例化时开始…...

网站禁止访问/怎么关键词优化网站

环境准备&#xff1a; 云主机&#xff08;香港节点&#xff09;&#xff08;CentOS7.4&#xff09;系统&#xff1a;CentOS7网卡名:eth0客户端&#xff08;win7&#xff09;&#xff08;红米安卓手机&#xff09;#由于pptpd需要iptables的支持&#xff0c;而centos7以后不再内置…...