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

C++ 顺序容器--vector容器详解

        元素保存在连续的内存空间中。插入元素或者删除元素通常需要线性时间,当这些操作在尾部执行时,实际运行时间为摊还常量时间。随机访问某个元素的复杂度为常量时间。

1 vector 概述

vector 在<vector>头文件中被定义为一个带有2个类型参数的类模板:一个参数为要保存的元素类型,另一个参数为分配器(allocator)类型。

template <class T, class Allocator = allocator<T>>  class  vector;

Allocator 参数指定了内存分配器对象的类型,客户可设置内存分配器,以便使用自定义的内存分配器。这个模板参数具有默认值。

从 C++20 开始,std::vector 是 constexpr,就像 std::string 一样。这意味着 vector 可用于在编译期执行操作,并可用于 constexpr 函数和类的实现。目前,vector 和 string 是唯一的 constexpr 的标准库容器。

1.1 固定长度的 vector

        使用vector 的最简单方式是将其用作固定长度的数组。vector 提供了一个可以指定元素数量的构造函数,还提供了一个重载的 operator口以便访问和修改这些元素。通过 operatorl访问 vector 边界之外的元素时,得到的结果是未定义的。也就是说,编译器可以自行决定如何处理这种情况。

        与真正的数组索引一样,vector 上的 operator[]没有提供边界检查功能。

        除使用 operator[]运算符外,还可通过 at()、front()和 back()访问 vector 中的元素。at()方法等同于operator[]运算符,区别在于at()会执行边界检查,如果索引超出边界,at()会抛出 out _of_range 异常。

        front()和back()分别返回 vector 的第1个元素和最后1个元素的引用。在空的容器上调用 front()和back()会引发未定义的行为.

        所有的vector元素访问操作的复杂度都是常量时间

vector<double> MyVector(10);

        vector的operator[]返回的是引用,可赋值,const vector的operator[]返回的是const元素引用,不能赋值。

1.2 动态长度的vector

vector<double>MyVector;MyVector.push_back();

2 vector详解

2.1 构造函数和析构函数

默认的构造函数创建一个不包含元素的 vector

vector<int> intVector; // Creates a vector of ints with zero elements

可指定元素个数,还可指定这些元素的值,如下所示:

vector<int> intVector (10, 100); // Creates vector of 10 ints with value 100

        如果没有提供默认值,那么对新对象进行0初始化。0初始化通过默认构造函数构建对象,将基本的整数类型(例如 char 和int 等)初始化为0,将基本的浮点类型初始化为0.0,将指针类型初始化为nullptr。
        还可创建内建类的 vector,如下所示:

vector<string> stringVector (10, "hello") ;

用户自定义的类也可以用作 vector 元素:

class Element
{public:Element () {}virtual ~Element ()= default;
};
vector<Element> elementVector;

        可以使用包含初始元素的 initializer_ list 构建 vector:

vector<int> intVector({1, 2, 3, 4, 5, 6 });

        统一初始化(uniform initialization)可用于包括 vector 在内的大部分标准库容器例如:

vector<int> intVectorl = { 1, 2, 3, 4, 5, 6 };
vector<int> intVector2{ 1, 2, 3, 4, 5, 6 };

        注意区分以下:

vector<int> intVector(10,100);//创建10个为100的元素
vector<int> intVector{10,100};//两个元素,10和100

        在自由存储区分配vector

auto elementVector { make_unique<vector<Element>>(10) };

2.2 vector的复制和赋值

        vector存储对象的副本,其析构函数调用每个对象的析构函数。vector类的拷贝构造和赋值运算符对vector中的所有元素执行深度复制。因此,出于效率方面的考虑,应该通过非const引用或者const引用而不是通过值向函数传递vector。

        assgin和swap

vector<int> intVector(10);
intVector.assgin(5,100);//删除所有元素并添加5个100
intVector.assgin({ 1 , 2 , 3 , 4 });vector<int> vectorOne(10);
vector<int> vectorTwo(5,100);
VectorOne.swap(vectorTwo);//交换,常量时间复杂度

2.3 vector的比较

        重载了==、!=、<、>、<=、>=。

        等于必须元素数量相等并对应元素相等。(每个元素必须可通过operator==比较)

        比较采用字典序。(每个元素必须可通过operator<比较)

2.4 迭代器

        尽量使用前递增++iter,返回引用,而后置返回新的迭代器对象

for(vector<double>::iterator iter{ begin(doubleVector) }; iter!=end(doubleVector);++iter){*iter/=1;
}
for(auto iter{ begin(doubleVector) }; iter!=end(doubleVector);++iter){}

        迭代器使用->

vector<string> stringVector(10,"hello");
for(auto it{begin(stringVector)};it!=end(stringVector);++it){it->append(" there");
}
for(auto& str:stringVector){str.append(" there");
}

const_iterator

        const对象调用begin()和end(),或调用cbegin()和end(),将得到const_iterator。

        iterator始终可以转换为const_iterator,反之不能。

安全性:不安全

        例如end()越过了vector的尾部,但不要求验证。

可前后移动,例如:it+=5,it--,*it=4;

2.5  pop_back()删除元素,但不会返回元素,通过back()获得元素

2.6 insert()

insert()五种重载:

1.插入单个元素

iterator insert(const_iterator position, const T& value);

 2.插入单个元素的n份副本

iterator insert(const_iterator position, size_type n, const T& value);

 4.使用移动语义,将给定元素转移到vector中,插入一个元素

iterator insert(const_iterator position, T&& value);

3.从某个迭代器范围插入元素

iterator insert(const_iterator position, InputIterator first, InputIterator last);

5.向vector中插入一系列元素,这列元素通过initializer_list指定

iterator insert(const_iterator position, std::initializer_list<T> il);

        以下提供了对应的简单示例:

int main() {// 示例 1: 在指定位置插入单个元素std::vector<int> vec1 = { 1, 2, 3 };auto it1 = vec1.insert(vec1.begin() + 1, 10); // 在位置 1 插入 10std::cout << "Example 1: ";for (int v : vec1) std::cout << v << " "; // 输出: 1 10 2 3std::cout << std::endl;// 示例 2: 在指定位置插入单个元素(右值引用)std::vector<std::string> vec2 = { "a", "b", "c" };auto it2 = vec2.insert(vec2.begin() + 1, std::string("x")); // 在位置 1 插入 "x"std::cout << "Example 2: ";for (const std::string& v : vec2) std::cout << v << " "; // 输出: a x b cstd::cout << std::endl;// 示例 3: 在指定位置插入多个相同元素std::vector<int> vec3 = { 1, 2, 3 };auto it3 = vec3.insert(vec3.begin() + 1, 3, 10); // 在位置 1 插入 3 个 10std::cout << "Example 3: ";for (int v : vec3) std::cout << v << " "; // 输出: 1 10 10 10 2 3std::cout << std::endl;// 示例 4: 在指定位置插入一个范围内的元素std::vector<int> vec4 = { 1, 2, 3 };std::vector<int> vec4_source = { 4, 5, 6 };auto it4 = vec4.insert(vec4.begin() + 1, vec4_source.begin(), vec4_source.end()); // 在位置 1 插入 vec4_source 的所有元素std::cout << "Example 4: ";for (int v : vec4) std::cout << v << " "; // 输出: 1 4 5 6 2 3std::cout << std::endl;// 示例 5: 在指定位置插入一个初始化列表中的元素std::vector<int> vec5 = { 1, 2, 3 };auto it5 = vec5.insert(vec5.begin() + 1, { 10, 20, 30 }); // 在位置 1 插入初始化列表 {10, 20, 30}std::cout << "Example 5: ";for (int v : vec5) std::cout << v << " "; // 输出: 1 10 20 30 2 3std::cout << std::endl;return 0;
}

2.7 erase()

两种重载:

iterator erase(const_iterator position);
iterator erase(const_iterator first, const_iterator last);

示例:

        注意范围版本移除的是[first,last),不包含last指向的元素

        线性时间,因为后面的元素要前移

int main() {// 示例 1: 移除单个元素std::vector<int> vec1 = { 1, 2, 3, 4, 5 };auto it1 = vec1.erase(vec1.begin() + 2); // 移除位置 2 的元素(值为 3)std::cout << "Example 1: ";for (int v : vec1) std::cout << v << " "; // 输出: 1 2 4 5std::cout << "\nIterator points to: " << *it1 << std::endl; // 输出: 4// 示例 2: 移除一个范围内的元素std::vector<int> vec2 = { 1, 2, 3, 4, 5 };auto it2 = vec2.erase(vec2.begin() + 1, vec2.begin() + 3); // 移除位置 1 和 2 的元素(值为 2 和 3)std::cout << "Example 2: ";for (int v : vec2) std::cout << v << " "; // 输出: 1 4 5std::cout << "\nIterator points to: " << *it2 << std::endl; // 输出: 4return 0;
}

2.8 clear() 

void clear() noexcept;

        不会抛出异常 

        通过示例看size和capacity的表现:

int main() {// 创建一个包含元素的 vectorstd::vector<int> vec = { 1, 2, 3, 4, 5 };// 输出初始状态std::cout << "Before clear:" << std::endl;std::cout << "Size: " << vec.size() << ", Capacity: " << vec.capacity() << std::endl;std::cout << "Elements: ";for (int v : vec) std::cout << v << " ";std::cout << std::endl;// 调用 clear 方法vec.clear();// 输出调用 clear 后的状态std::cout << "\nAfter clear:" << std::endl;std::cout << "Size: " << vec.size() << ", Capacity: " << vec.capacity() << std::endl;std::cout << "Elements: ";for (int v : vec) std::cout << v << " "; // 无输出,因为 vector 为空std::cout << std::endl;// 释放未使用的内存vec.shrink_to_fit();std::cout << "\nAfter shrink_to_fit:" << std::endl;std::cout << "Size: " << vec.size() << ", Capacity: " << vec.capacity() << std::endl;return 0;
}

        输出:

Before clear:
Size: 5, Capacity: 5
Elements: 1 2 3 4 5After clear:
Size: 0, Capacity: 5
Elements:After shrink_to_fit:
Size: 0, Capacity: 0

2.9 std::erase()和std::erase_if()

        如果要删除所有满足条件的元素,如果循环删除将有O(n^2)的复杂度,可以通过remove-erase-idiom避免,它具有线性复杂度。

        这里主要看C++20开始的std::erase()和std::erase_if()。

        示例如下:

int main() {std::vector<int> numbers1 = { 3, 1, 4, 1, 5, 9, 2, 6, 1 };// 删除所有值为 1 的元素auto count1 = std::erase(numbers1, 1);  // C++20 新方法std::cout << "删除后 vector: ";for (int num : numbers1) {std::cout << num << " ";  // 输出: 3 4 5 9 2 6}std::cout << "\n删除了 " << count1 << " 个元素\n";  // 输出: 3std::vector<int> numbers2 = { 3, 1, 4, 1, 5, 9, 2, 6, 1 };// 删除所有偶数(使用 Lambda 表达式)auto count2 = std::erase_if(numbers2, [](int x) { return x % 2 == 0; });std::cout << "删除后 vector: ";for (int num : numbers2) {std::cout << num << " ";  // 输出: 3 1 1 5 9 1}std::cout << "\n删除了 " << count2 << " 个元素\n";  // 输出: 3
}

2.10 移动语义

void PrintVector(const std::vector<std::string>& vec ) {std::cout << "PrintVector-->Start" << std::endl;for (const auto& it : vec) {std::cout << it << std::endl;}std::cout << "PrintVector-->End" << std::endl;
}int main() {std::vector<std::string> vec;vec.push_back(std::string(3,'a'));vec.push_back(std::string("Hello"));std::string s = "Hello";vec.push_back(std::move(s));  // 移动语义,s 的内容被“转移”到 vector// 此时 s 变为空(但仍是合法状态)PrintVector(vec);
}

        作为函数返回值返回值时,编译器会优化成移动语义。 

2.11 emplace_back()

        不复制或移动数据,直接分配空间然后构造

vec.push_back(string(5,'a'));
//or
vec.emplace_back(5,'a');

2.12 vector的内存分配方案

        当空间不够装下数据(vec.push_back(value))时,会自动申请另一片更大的空间(VS1.5倍或Linux2倍),然后把原来的数据拷贝到新的内存空间,接着释放原来的那片空间。

        当释放或者删除(vec.clear())里面的数据时,其存储空间不释放,仅仅是清空了里面的数据。

2.13 reserve()和resize()

reserve():

void reserve(size_type n);

        增加 vector 的容量(capacity()),以确保它可以容纳至少 n个元素。

        如果 n 大于当前容量(capacity()),则重新分配内存以增加容量。

        如果 n 小于或等于当前容量,则不会进行任何操作。

        不会改变 vector 的大小(size()),也不会创建或销毁任何元素。

        复杂度:最坏情况下为线性时间(需要重新分配内存并移动元素)

        适用场景:在已知需要存储大量元素时,提前分配足够的内存,避免多次重新分配。

resize():

void resize(size_type count);
void resize(size_type count, const T& value);

        改变 vector 的大小(size()),并根据需要添加或移除元素。

        如果 count 大于当前大小(size()),则在末尾添加新元素,直到大小达到 count。

        如果 count 小于当前大小,则移除末尾的多余元素。

        可能改变 vector 的容量(capacity()),但具体行为取决于实现。

        复杂度:线性时间

        适用场景:需要显式调整容器大小时使用。

2.14 全局std::size()(返回无符号整型),std::ssize()(返回有符号整型),std::empty()

2.15 用data()和std::data()获取指向内存的指针

vector<int> vec { 1 , 2 , 3 };
int* data1 { vec.data() };
int* data2 { data(vec) };

2.16 vector<bool>特化

        如果需要动态位字段,建议使用vector<std::int_fast8_t>或vector<unsigned_char>。

        如果要使用位字段建议使用bitset

相关文章:

C++ 顺序容器--vector容器详解

元素保存在连续的内存空间中。插入元素或者删除元素通常需要线性时间&#xff0c;当这些操作在尾部执行时&#xff0c;实际运行时间为摊还常量时间。随机访问某个元素的复杂度为常量时间。 1 vector 概述 vector 在<vector>头文件中被定义为一个带有2个类型参数的类模板…...

用Golang与WebAssembly构建高性能Web应用:详解`syscall/js`包

用Golang与WebAssembly构建高性能Web应用&#xff1a;详解syscall/js包 引言为什么选择syscall/js包&#xff1f;适用场景 syscall/js包概述syscall/js包的核心概念1. js.Global2. js.Value3. js.Func4. js.Null 和 js.Undefined syscall/js包在WebAssembly中的位置 环境配置与…...

LeetCode刷题 -- 23. 合并 K 个升序链表

小根堆排序与合并 K 个有序链表的实现 1. 介绍 本技术文档详细介绍了如何使用 小根堆&#xff08;Min Heap&#xff09; 实现 K 个有序链表的合并。 核心思想是&#xff1a; 使用 小根堆 维护当前最小的节点。每次取出堆顶元素&#xff08;最小值&#xff09;加入合并链表&…...

【每日八股】计算机网络篇(一):概述

OSI 的 7 层网络模型&#xff1f; OSI&#xff08;Open Systems Interconnection&#xff0c;开放互联系统&#xff09;是由国际标准化组织&#xff08;ISO&#xff09;提出的一种网络通信模型。 自上而下&#xff0c;OSI 可以被分为七层&#xff0c;分别是&#xff1a;应用层…...

业务应用和大数据平台的数据流向

概述 业务应用与大数据平台之间的交互是实现数据驱动决策和实时业务处理的关键环节。其交互方式多样&#xff0c;协议选择取决于数据流向、实时性要求及技术架构。一句话总结&#xff0c;数据流向可以是从业务应用写入大数据平台&#xff0c;也可以是大数据平台回写至业务应用…...

C语言中的文件和文件操作

文件操作 一、文件的打开和关闭二、文件的顺序读写fgetc和fputcfgets和fputsfscanf和fprintfsscanf和sprintffread和fwrite 三、文件的随机读写1.fseek2.ftell3.rewind 四、补充1.文件读取结束的判定2.文件缓冲区 一、文件的打开和关闭 流和标准流 流&#xff1a;想象为流淌着…...

插入排序:一种简单而直观的排序算法

大家好&#xff01;今天我们来聊聊一个简单却非常经典的排序算法——插入排序&#xff08;Insertion Sort&#xff09;。在所有的排序算法中&#xff0c;插入排序是最直观的一个。 一、插入排序的基本思想 插入排序的核心思想是&#xff1a;将一个待排序的元素&#xff0c;插…...

2.24力扣每日一题--设计有序流

1656. 设计有序流 - 力扣&#xff08;LeetCode&#xff09; &#xff08;设计一个可以存储n个字符串的数据结构&#xff0c;其中满足存在一个”指针“&#xff0c;用以展示当下是否还存在空间存储&#xff0c;每个字符串有自己ID需要存储&#xff09; 数据结构&#xff1a; 字…...

本地Oracle数据库复制数据到Apache Hive的Linux服务器集群的分步流程

我们已经有安装Apache Hive的Linux服务器集群&#xff0c;它可以连接到一个Oracle RDS数据库&#xff0c;需要在该Linux服务器上安装配置sqoop&#xff0c;然后将Oracle RDS数据库中所有的表数据复制到Hive。 为了将本地Oracle数据库中的所有表数据复制到Apache Hive Linux服务…...

【R语言】ggplot2绘图常用操作

目录 坐标轴以及标签的相关主题 图例调整 字体类型设置 颜色相关 ggplot2如何添加带箭头的坐标轴&#xff1f; 标题相关主题调整 修改点图中点的大小 如何使得点的大小根据变量取值的大小来改变&#xff1f; 柱状图和条形图 坐标轴以及标签的相关主题 theme( # 增大X…...

正态分布的奇妙性质:为什么奇数阶中心矩(odd central moments)为零?

正态分布的奇妙性质&#xff1a;为什么奇数阶矩为零&#xff1f; 正态分布&#xff08;Normal Distribution&#xff09;是统计学中最常见的分布之一&#xff0c;它的钟形曲线几乎无处不在&#xff0c;从身高体重到测量误差&#xff0c;都能看到它的影子。除了均值和方差这两个…...

架构——Nginx功能、职责、原理、配置示例、应用场景

以下是关于 Nginx 的功能、职责、原理、配置示例、应用场景及其高性能原因的详细说明&#xff1a; 一、Nginx 的核心功能 1. 静态资源服务 功能&#xff1a;直接返回静态文件&#xff08;如 HTML、CSS、JS、图片、视频等&#xff09;。配置示例&#xff1a;server {listen 80…...

涉密载体管控系统革新:RFID技术引领,信息安全新境界

行业背景 文件载体管控系统DW-S402是用于对各种SM载体进行有效管理的智能柜&#xff08;智能管理系统&#xff09;&#xff0c;实现对载体的智能化、规范化、标准化管理&#xff0c;广泛应用于保密、机要单位以及企事业单位等有载体保管需求的行业。 随着信息化技术发展&…...

基于 SpringBoot 的 “电影交流平台小程序” 系统的设计与实现

大家好&#xff0c;今天要和大家聊的是一款基于 SpringBoot 的 “电影交流平台小程序” 系统的设计与实现。项目源码以及部署相关事宜请联系我&#xff0c;文末附上联系方式。 项目简介 基于 SpringBoot 的 “电影交流平台小程序” 系统设计与实现的主要使用者分为 管理员 和…...

【Rust中级教程】2.9. API设计原则之显然性(obvious) :文档与类型系统、语义化类型、使用“零大小”类型

喜欢的话别忘了点赞、收藏加关注哦&#xff08;加关注即可阅读全文&#xff09;&#xff0c;对接下来的教程有兴趣的可以关注专栏。谢谢喵&#xff01;(&#xff65;ω&#xff65;) 2.9.1. 文档与类型系统 用户可能不会完全理解API的所有规则和限制。所以你写的API应该让你…...

git branch

文章目录 1.简介2.格式3.选项4.示例参考文献 1.简介 git branch 用于管理分支&#xff0c;包括查看、创建、删除、重命名和关联。 git branch 是 Git 版本控制系统中用于管理分支的命令。分支是 Git 的核心功能之一&#xff0c;允许开发者在同一个代码库中并行开发不同的功能…...

【网络编程】广播和组播

数据包发送方式只有一个接受方&#xff0c;称为单播。如果同时发给局域网中的所有主机&#xff0c;称为广播。只有用户数据报(使用UDP协议)套接字才能广播&#xff1a; 广播地址以192.168.1.0 (255.255.255.0) 网段为例&#xff0c;最大的主机地址192.168.1.255代表该网段的广…...

运维Crontab面试题及参考答案

Crontab 文件的六个域分别是什么&#xff1f;顺序如何&#xff1f; Crontab 文件用于设置定时执行任务&#xff0c;其六个域及顺序从左到右依次为&#xff1a;分钟&#xff08;Minute&#xff09;、小时&#xff08;Hour&#xff09;、日期&#xff08;Day of month&#xff09…...

Lecture 1 - AI Systems (Overview)

一、Machine Learning Approach标准机器学习流程 • Train ML algorithm&#xff08;训练机器学习算法&#xff09;&#xff1a;基于收集的数据训练机器学习模型。 二、Machine Learning for Adaptation&#xff08;适应性机器学习&#xff09; 加入了数据更新和自动化的部分…...

Ansible 学习笔记

这里写自定义目录标题 基本架构文件结构安装查看版本 Ansible 配置相关文件主机清单写法 基本架构 Ansible 是基于Python实现的&#xff0c;默认使用22端口&#xff0c; 文件结构 安装 查看用什么语言写的用一下命令 查看版本 Ansible 配置相关文件 主机清单写法...

设计模式-结构型-代理模式

1. 代理模式概述 代理模式&#xff08;Proxy Pattern&#xff09; 是一种结构型设计模式&#xff0c;它允许通过代理对象来控制对目标对象的访问。代理模式主要用于以下场景&#xff1a; 控制对象访问&#xff1a;限制某些对象的访问权限&#xff0c;例如权限控制。 延迟实例…...

FCC CE SRRC MIC是什么意思?

1.FCC CE SRRC MIC是什么意思&#xff1f; 2.4000 GHz 至 2.4835 GHz&#xff1a;<33 dBm&#xff08;FCC&#xff09;&#xff0c;<20 dBm&#xff08;CE/SRRC/MIC&#xff09; 5.150 GHz 至 5.250 GHz&#xff08;CE&#xff1a;5.170 GHz 至 5.250 GHz&#xff09;&a…...

springboot005学生心理咨询评估系统(源码+数据库+文档)

源码地址&#xff1a;学生心理咨询评估系统 文章目录 1.项目简介2.部分数据库结构与测试用例3.系统功能结构4.包含的文件列表&#xff08;含论文&#xff09;后台运行截图 1.项目简介 ​ 使用旧方法对学生心理咨询评估信息进行系统化管理已经不再让人们信赖了&#xff0c;把现…...

Apache Doris:一款高性能的实时数据仓库

Apache Doris 是一款基于 MPP 架构的高性能、实时分析型数据库。它以高效、简单和统一的特性著称&#xff0c;能够在亚秒级的时间内返回海量数据的查询结果。Doris 既能支持高并发的点查询场景&#xff0c;也能支持高吞吐的复杂分析场景。 Apache Doris 最初是百度广告报表业务…...

使用Vue-Flow创建一个流程图可视化节点坐标查询器

在开发中遇到这样一个需求&#xff0c;需要后端返回数据前端网页生成流程图&#xff0c;由于流程图使用了Vue-Flow&#xff0c;所以需要坐标来辅助后端生成数据。 首先引入方法并定义添加节点数据 const { updateEdge, addEdges, addNodes} useVueFlow() const add_nodes …...

面试基础--Java 集合框架详解

Java 集合框架详解&#xff1a;从 ArrayList 到 HashMap 的底层原理 引言 在 Java 开发中&#xff0c;集合框架&#xff08;Collection Framework&#xff09;是处理数据存储和操作的核心工具。无论是日常开发还是大厂面试&#xff0c;对集合框架的理解都是考察的重点之一。本…...

轻量级日志管理平台Grafana Loki

文章目录 轻量级日志管理平台Grafana Loki背景什么是Loki为什么使用 Grafana Loki&#xff1f;架构Log Storage Grafana部署使用基于 Docker Compose 安装 LokiMinIO K8s集群部署Loki采集Helm 部署方式和案例 参考 轻量级日志管理平台Grafana Loki 背景 在微服务以及云原生时…...

回文串

长度为偶数的串&#xff0c;重排连续字串变成回文串。 Problem - D - Codeforces 代码&#xff1a; #include <bits/stdc.h> #define fi first #define se second using namespace std; typedef long long LL; typedef pair<int,int> PII; typedef pair<LL,L…...

《跟李沐学 AI》AlexNet论文逐段精读学习心得 | PyTorch 深度学习实战

前一篇文章&#xff0c;使用 AlexNet 实现图片分类 | PyTorch 深度学习实战 本系列文章 GitHub Repo: https://github.com/hailiang-wang/pytorch-get-started 本篇文章内容来自于学习 9年后重读深度学习奠基作之一&#xff1a;AlexNet【下】【论文精读】】的心得。 《跟李沐…...

【电机控制器】FU6832S——持续更新

【电机控制器】FU6832S——持续更新 文章目录 [TOC](文章目录) 前言一、ADC二、UART三、PWM四、参考资料总结 前言 使用工具&#xff1a; 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 一、ADC 二、UART 三、PWM 四、参考资料 总结 本文仅仅简…...