【爱上C++】vector用法详解

文章目录

  • 一:vector简介
  • 二:vector的创建和初始化
  • 三:vector的遍历
    • 1.[]+下标
    • 2.at()
    • 3.迭代器遍历
    • 4.范围for
  • 四:vector的空间
    • 1.size
    • 2.max_size
    • 3.capacity
    • 4.reserve
    • 5.resize
    • 6.empty
  • 五:vector的增删查改
    • 1.push_back
    • 2.pop_back
    • 3.find
    • 4.insert
    • 5.erase
    • 6.swap
    • 7.assign

Hello~同学们好,本文将深入探讨 C++ 中的 vector 容器,作为标准模板库(STL)中最常用的动态数组之一,vector 提供了灵活的元素存储和高效的访问方法。我们将从基础知识入手,逐步学习其创建、初始化、遍历、空间管理以及增删查改等操作。通过详细的示例和解析,希望能够帮助读者全面理解和掌握 vector 的使用技巧和注意事项。

一:vector简介

vector文档

  1. vector是表示可变大小数组的序列容器。
  2. 就像数组一样,vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素进行访问,和数组一样高效。但是又不像数组,它的大小是可以动态改变的,而且它的大小会被容器自动处理。
  3. 本质讲,vector使用动态分配数组来存储它的元素。当新元素插入时候,这个数组需要被重新分配大小为了增加存储空间。其做法是,分配一个新的数组,然后将全部元素移到这个数组。就时间而言,这是一个相对代价高的任务,因为每当一个新的元素加入到容器的时候,vector并不会每次都重新分配大小。
  4. vector分配空间策略:vector会分配一些额外的空间以适应可能的增长,因为存储空间比实际需要的存储空间更大。不同的库采用不同的策略权衡空间的使用和重新分配。但是无论如何,重新分配都应该是对数增长的间隔大小,以至于在末尾插入一个元素的时候是在常数时间的复杂度完成的。
  5. 因此,vector占用了更多的存储空间,为了获得管理存储空间的能力,并且以一种有效的方式动态增长。
  6. 与其它动态序列容器相比(deque, list and forward_list), vector在访问元素的时候更加高效,在末尾添加和删除元素相对高效。对于其它不在末尾的删除和插入操作,效率更低。比起list和forward_list统一的迭代器和引用更好。


使用STL的三个境界:能用,明理,能扩展 ,那么下面学习vector,我们也是按照这个方法去学习

二:vector的创建和初始化

要包头文件#include<vector>

    // 默认构造函数,创建一个空的 vector
    vector<int> v1; 
    
    // 创建一个包含 4 个默认初始化元素(值为 0)的 vector
    vector<int> v2(4); 
    
    // 创建一个包含 4 个元素,每个元素初始化为 10 的 vector
    vector<int> v3(4, 10); 
    
    // 使用迭代器范围(v3 的起始和结束迭代器)初始化 vector,v4 将包含 v3 的所有元素
    vector<int> v4(v3.begin(), v3.end());
    
    // 拷贝构造函数,创建一个 v2 的副本
    vector<int> v5(v2); 
    
    // 使用初始化列表创建 vector,v6 将包含 1, 2, 3, 4, 5, 6, 7 这些元素
    vector<int> v6 = {1, 2, 3, 4, 5, 6, 7}; 

    // 使用 std::string 初始化
    string s1("12345"); // 创建一个包含 "12345" 的字符串 s1
    // 使用 std::string 的迭代器初始化 std::vector<int>
    // 这里每个 char 会隐式转换为其对应的 int(ASCII 值)
    vector<int> v3(s1.begin(), s1.end()); // 使用字符串的迭代器初始化 vector<int>

vector和string的区别:


std::vector:

  • 不自动添加 \0:
    • std::vector 只是一个通用的动态数组容器,它不会在末尾自动添加 \0。你需要手动管理字符串的结束标志。
    • 当你需要将 std::vector 转换为 C 风格字符串时,你必须手动添加一个 \0。


std::string:

  • 自动添加 \0:
    • std::string 在内部管理一个以 \0 结尾的字符数组。这个空字符保证了字符串可以直接使用 C 风格字符串的函数。
    • 当你创建或操作 std::string 对象时,\0 是自动添加和管理的,因此不需要手动处理。

三:vector的遍历

1.[]+下标

image.png

void test_vector1()
{
	vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);
	for (size_t i = 0; i < v.size(); i++)
	{
		cout << v[i] << " ";
	}
	cout << endl;
}

看一下结果(push_back后面会将,顾名思义也就是尾插)
image.png
调试一下看看image.png

2.at()

image.png
at() 函数用于访问vector 中的元素,并进行边界检查。与 operator[] 不同,at() 会在访问越界时抛出 std::out_of_range 异常,因此它比 operator[] 更安全,但稍微有点性能开销。

#include <iostream>  // 引入输入输出流头文件
#include <vector>    // 引入 vector 容器头文件
#include <stdexcept> // 引入标准异常头文件
using namespace std; // 使用标准命名空间
int main() {
	vector<int> vec = { 10, 20, 30, 40, 50 }; // 初始化一个包含五个整数的 vector

	// 正常访问 vector 的元素
	try {
		for (size_t i = 0; i < vec.size(); ++i) {
			cout << "Element at index " << i << " is " << vec.at(i) << endl; // 使用 at() 函数访问元素
		}
	}
	catch (const out_of_range& e) {
		cerr << "Out of range error: " << e.what() << endl; // 捕捉并处理越界访问异常
	}
	// 尝试访问越界元素
	try {
		cout << "Element at index 10 is " << vec.at(10) << endl; // 访问索引为 10 的元素,这将抛出异常
	}
	catch (const out_of_range& e) {
		cerr << "Out of range error————" << e.what() << endl; // 捕捉并处理越界访问异常
	}

	return 0; // 返回 0 表示程序正常结束
}

image.png

3.迭代器遍历

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

image.png
迭代器访问+修改

    vector<int> v1;        // 定义一个空的 vector 容器
    v1.push_back(1);       // 向容器中添加元素 1
    v1.push_back(2);       // 向容器中添加元素 2
    v1.push_back(3);       // 向容器中添加元素 3
    v1.push_back(4);       // 向容器中添加元素 4
    
    vector<int>::iterator it = v1.begin(); // 初始化迭代器,指向 vector 的起始位置
    
    // 使用 while 循环遍历 vector 的元素
    while (it != v1.end()) {                // 当迭代器未到达 vector 的末尾时继续循环
        *it -= 10;                          // 将迭代器指向的元素值减去 10
        cout << *it << " ";                 // 打印当前元素值
        it++;                               // 迭代器指向下一个元素
    }
    cout << endl;                           // 输出换行符

为什么 while (it != v1.end())不能用 it<v1.end()?
因为在 C++ 中,标准库容器(如 std::vector)的迭代器支持比较操作,但通常是使用 != 而不是 < 来判断迭代器是否已经到达容器的末尾。!= 比较更加直观和符合语义。
使用 < 进行比较可能在某些情况下无效,因为并不是所有迭代器都支持 < 运算符。特别是,对于双向迭代器或更复杂的迭代器(如关联容器中的迭代器),它们不支持这种操作。

注意:vector<int>::iterator it = v1.begin();要用vector::指明是什么类型的迭代器。

4.范围for

void vector_Traversal_test() {
	vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);
 
	// 范围for
	for (auto e : v) {
		cout << e << " ";
	}
	cout << endl;
 
	for (auto& e : v) {
		e += 10;
		cout << e << " ";
	}
	cout << endl;

//范围for实际上是使用迭代器来遍历容器的
//把上面两个展开其实是下面两个。
    for (auto it = v.begin(); it != v.end(); ++it)
    {
    auto e = *it;  // 通过迭代器获取当前元素
    cout << e << " ";
    }
    cout << endl;

    for (auto it = v.begin(); it != v.end(); ++it) 
    {
    auto& e = *it;  // 通过迭代器获取当前元素的引用
    e += 10;        // 修改元素的值
    cout << e << " ";
    }
    cout << endl;
}

四:vector的空间


size获取数据个数
max_size容器所能容纳的最大元素数量
capacity获取容量大小
resize改变vector的size
reserve改变vector的capacity
empty判断是否为空

1.size

size() 函数返回当前 vector 中的元素个数。

2.max_size

max_size() 函数返回 vector 可以容纳的最大元素数量,这个数量通常是一个非常大的值,取决于系统限制和内存可用性。

3.capacity

capacity() 函数返回当前 vector 内部存储空间的容量,即在重新分配之前可以存储的元素数量。

4.reserve

reserve(n) 函数用于请求 vector 预留足够的存储空间,以容纳至少 n 个元素。这样做可以减少因为容器扩展而导致的重新分配操作,提高插入元素的效率。
如果已经确定vector中要存储元素大概个数,可以提前将空间设置足够,就可以避免边插入边扩容导致效率低下的问题了

void TestVectorExpandOP()
{
	vector<int> v;
	size_t sz = v.capacity();
	v.reserve(100); // 提前将容量设置好,可以避免一遍插入一遍扩容
	cout << "making bar grow:\n";
	for (int i = 0; i < 100; ++i)
	{
		v.push_back(i);
		if (sz != v.capacity())
		{
			sz = v.capacity();
			cout << "capacity changed: " << sz << '\n';
		}
	}
}

5.resize

resize() 函数用于改变 vector 的大小,即容器中元素的数量。它可以根据传入的参数 n,进行不同的操作:

  1. 当 n < size 时
    • 容器尾部多余的元素会被销毁。
    • capacity 不会改变。
  2. 当 size <= n <= capacity 时
    • 容器尾部新增加的元素被初始化为默认值(对于 int 类型,默认值是 0)。
    • capacity 不会改变。
  3. 当 n > capacity 时
    • 容器尾部新增加的元素被初始化为默认值。
    • size 和 capacity 都会变为 n,并且需要重新分配内存来扩展容器的存储空间。

6.empty

empty() 函数检查 vector 是否为空,如果 vector 中没有元素,则返回 true,否则返回 false。

五:vector的增删查改

push_back尾插
pop_back尾删
find查找(注意这个是算法模块实现,不是vector的成员接口)
insert在pos位置之前插入数据
erase删除pos位置的数据
swap交换两个vector的数据空间
assign用于将新值分配给向量的元素,替换当前内容,并修改向量的大小

1.push_back

	vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	for (auto e : v)
	{
		cout << e << " ";
	}
	cout << endl;
	
	vector<string> v1;
	v1.push_back(" we");
	v1.push_back(" all");
	v1.push_back(" love");
	v1.push_back(" C++");

	for (auto e : v1)
	{
		cout <<e;
	}
	cout << endl;

image.png

2.pop_back

void test_vector5() {
	vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	for (auto e : v) cout << e << " "; cout << endl;
 
	v.pop_back();   // 尾删:3
	for (auto e : v) cout << e << " "; cout << endl;
	
	v.pop_back();   // 尾删:2
	for (auto e : v) cout << e << " "; cout << endl;
}

3.find

思考:为什么string、map、set、都有自己的find而vector和list没有?


为什么 string、map、set 提供 find 操作?

  • std::string
    • std::string 是一个字符序列,提供 find 操作用于子串查找,这是字符串操作中非常常见的需求。
    • 例如,查找某个子串在字符串中的位置。
  • std::map 和 std::set
    • std::map 和 std::set 是关联容器,基于平衡二叉树(如红黑树)实现。
    • find 操作在这些容器中是核心功能,因为它们的主要用途就是快速查找键。
    • std::map 提供键值对的查找,而 std::set 提供唯一键的查找。
    • 这些容器的查找操作效率是 O(log n)。

      为什么 vector 和 list 不提供 find 操作?
  • std::vector
    • std::vector 是一个动态数组,主要用于顺序存储和访问。
    • 查找操作的效率是 O(n),因为需要线性扫描整个数组。
    • 提供 find 操作在效率上不占优势,因此没有直接提供。
  • std::list
    • std::list 是一个双向链表,适用于频繁插入和删除操作。
    • 查找操作的效率同样是 O(n),因为需要线性扫描链表。
    • 和 vector 类似,提供 find 操作在效率上不占优势,因此没有直接提供。
#include <algorithm>
void test_vector9()
{
	vector<int> v;
	v.push_back(9);
	v.push_back(9);
	v.push_back(6);
	
	vector<int>::iterator it = find(v.begin(), v.end(),6);
	if (it != v.end())
	{
		cout << "找到啦" << endl;
		cout << *it << endl;
	}
}

4.insert

image.png

void test_vector9()
{
	vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);
	v.push_back(5);
	v.push_back(6);
	auto it1 = v.begin() + 2;//在第三个位置插入
	v.insert(it1, 100);
	for (auto e : v)
	{
		cout << e << " ";
	}//1 2 100 3 4 5 6
	cout << endl;

	auto it2 = v.begin() + 4;
	v.insert(it2, 3, 90);//在第五个位置插入3个90
	for (auto e : v)
	{
		cout << e << " ";
	}//1 2 100 3 90 90 90 4 5 6
	cout << endl;


	vector<int> vec1 = { 1, 2, 6 };
	vector<int> vec2 = { 3, 4, 5 };
	auto it3 = vec1.begin() + 2; // 在第三个位置插入元素
	vec1.insert(it3, vec2.begin(), vec2.end()); // 在位置 it 处插入 vec2 的所有元素
	// 现在 vec1 = {1, 2, 3, 4, 5, 6}
}

注意:pos的类型都是iterator;

5.erase

image.png

    vector<int> v {1, 2, 3, 4, 5};

    // 删除第三个元素
    auto it = v.erase(v.begin() + 2);
    // v = {1, 2, 4, 5}
    for (auto elem : v) {
        cout << elem << " ";
    }
    cout << endl;

    // 删除第二个到第四个元素
    auto first = v.begin() + 1;
    auto last = v.begin() + 4;
    v.erase(first, last);
    // v = {1, 5}
    for (auto elem : v) {
        cout << elem << " ";
    }
    cout << endl;
//注意:[first,last) 是左闭右开的区间所以last可以取v.begin() + 4
  • 在调用 erase 后,被移除的元素会被析构,相关的内存也会被释放。
  • 对于 erase(iterator first, iterator last),注意 first 和 last 的有效性和顺序,确保不会越界访问或者非法操作。
  • 删除元素后,后续的元素会向前移动填补空缺,保持 vector 的连续性。
  • erase 操作可能会导致迭代器失效,因此在使用返回的迭代器之前,要确保其仍然有效。

迭代器失效问题我会放在vector模拟实现(下一篇文章)详细讲解。

6.swap

std::vector 提供了一个成员函数 swap,用于交换两个 vector 对象的内容。这个操作可以快速地交换两个容器的元素,而不需要复制它们的内容。

    vector<int> v1 {1, 2, 3};
    vector<int> v2 {4, 5, 6};
    // 使用 swap 交换两个 vector 的内容
    v1.swap(v2);

    cout << "After swapping:\n";
    cout << "v1: ";
    for (auto elem : v1) {
        cout << elem << " ";  //4 5 6
    }
    cout << "\nv2: ";
    for (auto elem : v2) {
        cout << elem << " ";  //1 2 3
    }
    cout << endl;


效果和注意事项

  1. 内容交换:swap 函数会交换两个 vector 对象的所有元素,包括它们的大小(size)和容量(capacity)。
  2. 高效性:swap 操作非常高效,因为它只涉及指针的交换,不需要复制元素。这对于大型的 vector 特别有用,可以在不重新分配内存的情况下快速交换数据。
  3. 迭代器和引用的影响:swap 操作不会使现有的迭代器、引用和指针失效,因此可以安全地在 swap 后继续使用交换后的 vector 对象。
  4. 使用场景:swap 可以用于重新排序或重新组织数据,也可以用于优化内存使用,比如在算法中交换两个 vector 来实现更高效的数据处理流程。
  5. 示例: 上面的示例展示了如何使用 swap 将两个 vector 对象的内容进行交换,从而在输出中显示了交换后的结果。

总之,std::vector 的 swap 函数是一个非常有用的工具,能够快速、高效地交换两个 vector 对象的内容,适合在需要优化内存使用或者重新组织数据时使用。

7.assign

void demonstrate_assign() {
    // 创建一个空的 vector<int>
    vector<int> v;

    // 使用 assign(n, value) 方法赋值
    v.assign(5, 10); // 用5个10替换当前内容
    cout << "After v.assign(5, 10): ";
    for (int i : v) {
        cout << i << " "; // 输出: 10 10 10 10 10
    }
    cout << endl;

    // 使用 assign(first, last) 方法赋值
    int arr[] = {1, 2, 3, 4, 5};
    v.assign(arr, arr + 3); // 用数组的前3个元素替换当前内容
    cout << "After v.assign(arr, arr + 3): ";
    for (int i : v) {
        cout << i << " "; // 输出: 1 2 3
    }
    cout << endl;

    // 使用 vector 的迭代器范围赋值
    vector<int> v2 = {7, 8, 9};
    v.assign(v2.begin(), v2.end()); // 用v2的所有元素替换当前内容
    cout << "After v.assign(v2.begin(), v2.end()): ";
    for (int i : v) {
        cout << i << " "; // 输出: 7 8 9
    }
    cout << endl;
}

07c03ae6d77b4b153f6d1ec710be7c14_7a80245f0b5f4021a033b3789a9efdeb.png
📜 [ 声明 ] 由于作者水平有限,本文有错误和不准确之处在所难免,
本人也很想知道这些错误,恳望读者批评指正!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/782924.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ESP32CAM物联网教学10

ESP32CAM物联网教学10 MicroPython 应用体验 小智偶然地发现&#xff0c;有一种新兴的编程模式MicroPython&#xff0c;也能编写ESP32Cam的应用程序了&#xff0c;于是欣然地体验了一把。 编程环境搭建 小智偶然地从下面这家店铺买了一块ESP32Cam&#xff0c;并从客服那里得到…

【人工智能】-- 智能家居

个人主页&#xff1a;欢迎来到 Papicatch的博客 课设专栏 &#xff1a;学生成绩管理系统 专业知识专栏&#xff1a; 专业知识 文章目录 &#x1f349;引言 &#x1f349;基于深度卷积神经网络的表情识别 &#x1f348;流程图 &#x1f348;模型设计 &#x1f34d;网络架…

复旦微JFMVU3P-2FFVC1517 FPGA+AI全国产化人工智能数据处理平台,适用于雷达与中频信号采集、视频图像采集

板载FPGA实时处理器&#xff1a;JFMVU3P-2FFVC1517支持1个FMC&#xff08;HPC&#xff09;扩展接口支持2路QSFP光纤接口支持x8 Gen3 PCIE主机接口&#xff0c;系统带宽&#xff1e;5GByte/s支持1个R45自适应千兆以太网口支持1个GPIO/RS422接口 基于复旦微16nm工艺JFM9VU3P FPG…

【Linux】记录一起网站劫持事件

故事很短&#xff0c;处理也简单。权当记录一下&#xff0c;各位安全大大们手下留情。 最近一位客户遇到官网被劫持的情况&#xff0c;想我们帮忙解决一下&#xff08;本来不关我们的事&#xff0c;毕竟情面在这…还是无偿地协助一下&#xff09;&#xff0c;经过三四轮“谦让…

Java-SpringBoot启动报端口被占用,如何找到占用端口的进程并杀掉

背景 当我们本地启动多个项目&#xff0c;可能会出现端口被占用的情况&#xff0c;当然有时候可能idea窗口关闭&#xff0c;但是进程并没有kill掉&#xff0c;导致再次启动项目时也会报端口被占用的错误。 通常的做法是打开任务管理器&#xff0c;然后kill掉对应的进程。 首先…

“除了C盘都不见了“:现象解析、恢复策略与预防之道

现象概述&#xff1a;非系统盘突然消失之谜 在日常的计算机使用中&#xff0c;不少用户可能遭遇过一个令人措手不及的问题——“除了C盘都不见了”。这一现象发生时&#xff0c;用户惊讶地发现除了作为系统盘的C盘外&#xff0c;原本存放着各类文档、图片、视频等个人资料的D盘…

在一行中实现每个盒子间隔相等

达成效果&#xff1a; 1. 使用justify-content: space-evenly; <!DOCTYPE html> <html lang"zh-cn"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"…

Nginx Lua Waf 插件一键部署

文章目录 一、场景说明二、脚本职责三、参数说明四、操作示例五、注意事项 一、场景说明 本自动化脚本旨在为提高研发、测试、运维快速部署应用环境而编写。 脚本遵循拿来即用的原则快速完成 CentOS 系统各应用环境部署工作。 统一研发、测试、生产环境的部署模式、部署结构、…

直播平台集成美颜工具详解:视频美颜SDK开发指南

本篇文章&#xff0c;小编将详细介绍如何在直播平台中集成美颜工具&#xff0c;帮助开发者更好地理解视频美颜SDK的开发过程。 一、美颜工具的作用和原理 1.1 美颜工具的作用 美颜工具主要用于提升直播视频的画面质量&#xff0c;让主播和观众在镜头前看起来更加美观。这些功…

哈喽GPT-4o,程序员如何通过GPT-4o提高工作效率

目录 一、编写代码Prompt&#xff1a;请用Java语言编写一个二分查找的样例 二、修正代码错误、代码优化Prompt&#xff1a;我们上传一张华为OD算法题的题目描述&#xff0c;再给它我的Java解题代码&#xff0c;问问它有什么问题&#xff1f; 三、解读代码功能、代码翻译Prompt&…

【Arduino】XIAOFEIYU(TM)实验ESP32使用霍尔传感器(图文)

霍尔传感器是一种可以测量磁力变化的传感器&#xff0c;今天XIAOFEIYU就来测试一下ESP32使用霍尔传感器。 霍尔传感器&#xff1a;正负极加一个数据接口。 将传感器与ESP32进行电路连接&#xff1a; 编写程序&#xff1a; #define SIGNAL_PIN 33int value 0; // 存储传感…

51单片机-第一节-LED和独立按键

一、点亮LED&#xff1a; 首先包含头文件 <REGX52.H> 随后令P2为0xFE。(此时二进制对应1111 1110&#xff0c;为0 的LED亮&#xff0c;故八个灯中的最后一个亮起)。 注&#xff1a;P2为控制LED的8位寄存器。 void main() {P2 0xFE;//1111 1110while(1){} } 二、L…

《算法笔记》总结No.3——排序

基础算法之一&#xff0c;相当重要。在普通的机试中如果没有数据类型和时空限制&#xff0c;基本上选择自己最熟悉的就好。本篇只总结选择排序和插入排序&#xff0c;侧重应用&#xff0c;408中要求的种类更加繁多&#xff0c;此处先不扩展难度~总结最常用的两种排序。 一.选择…

腾讯课堂即将停止服务?来试试这款开源的知识付费系统

项目介绍 本系统基于ThinkPhp5.0layuiVue开发,功能包含在线直播、付费视频、付费音频、付费阅读、会员系统、分销系统、拼团活动、直播带货、直播打赏、商城系统等。能够快速积累客户、会员数据分析、智能转化客户、有效提高销售、吸引流量、网络营销、品牌推广的一款应用&…

javaIO流(2)

一.字符流 字符流对数据的操作是以一个个字符为单位的,字符流只能读文本文件,并将读到的字节按照编码表转为对应的字符,Reader和Writer是字符流的两个最大的抽象类,InputStreamReader和OutputStreamWriter分别继承了Reader和Writer,它俩的功能就是将读取到的字节转换为字符,所…

【大模型LLM面试合集】大语言模型基础_NLP面试题

NLP面试题 1.BERT 1.1 基础知识 BERT&#xff08;Bidirectional Encoder Representations from Transformers&#xff09;是谷歌提出&#xff0c;作为一个Word2Vec的替代者&#xff0c;其在NLP领域的11个方向大幅刷新了精度&#xff0c;可以说是近年来自残差网络最优突破性的…

流程图编辑框架LogicFlow-vue-ts和js

LogicFlow官网https://site.logic-flow.cn/LogicFlow 是一款流程图编辑框架&#xff0c;提供了一系列流程图交互、编辑所必需的功能和灵活的节点自定义、插件等拓展机制。LogicFlow支持前端研发自定义开发各种逻辑编排场景&#xff0c;如流程图、ER图、BPMN流程等。在工作审批配…

数据结构/作业/2024/7/7

搭建个场景: 将学生的信息&#xff0c;以顺序表的方式存储&#xff08;堆区)&#xff0c;并且实现封装函数︰1】顺序表的创建&#xff0c; 2】判满、 3】判空、 4】往顺序表里增加学生、5】遍历、 6】任意位置插入学生、7】任意位置删除学生、8】修改、 9】查找(按学生的学号查…

不同层数PCB如何选择合适板厚?

在回答这个问题前&#xff0c;我们首先需要了解什么是PCB厚度。 PCB厚度是指电路板完成后的厚度。 覆铜板的厚度&#xff1a;0.5、0.7、0.8、1.0、1.2、1.5、1.6、2.0、2.4、3.2和6.4毫米。 纸基覆铜板的标称厚度为 0.7 至 1.5 毫米。让我们开始了解更多细节。 标准 PCB 铜厚度…

使用GZip对npm run build打包的vendor.js文件进行压缩

vue-cli项目 安装npm i compression-webpack-plugin -D npm i compression-webpack-plugin -D使用&#xff1a;在vue.config.js文件中 const CompressionPlugin require(compression-webpack-plugin) module.exports {configureWebpack: {plugins: [new CompressionPlugin…