长春有几个站可以坐火车/seo软件视频教程
1. list的介绍及使用
1.1 list的介绍(双向循环链表)
https://cplusplus.com/reference/list/list/?kw=list(list文档介绍)
1. list是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代。
2. list的底层是双向链表结构,双向链表中每个元素存储在互不相关的独立节点中,在节点中通过指针指向其前一个元素和后一个元素。
3. list与forward_list非常相似:最主要的不同在于forward_list是单链表,只能朝前迭代,已让其更简单高效。
4. 与其他的序列式容器相比(array,vector,deque),list通常在任意位置进行插入、移除元素的执行效率更好。
1.2 list的使用(可以对照模拟实现看,重要的都有,后边模拟实现都会讲)
list中的接口比较多,此处类似,只需要掌握如何正确的使用,然后再去深入研究背后的原理,已达到可扩展的能力。以下为list中一些常见的重要接口。
1.2.1 list的构造
1.2.2 list iterator的使用
此处,大家可暂时将迭代器理解成一个指针,该指针指向list中的某个节点。
【注意】
1. begin与end为正向迭代器,对迭代器执行++操作,迭代器向后移动
2. rbegin(end)与rend(begin)为反向迭代器,对迭代器执行++操作,迭代器向前移动
1.2.3 list capacity
1.2.4 list element access
1.2.5 list modifiers
list中还有一些操作,需要用到时大家可参阅list的文档说明。
1.2.6 list的迭代器失效
注意,insert不会失效,迭代器依旧指向原来位置,erase会失效(删除后返回下一个地址),跟vector的迭代器失效类比,都是因为没有接收删除后的迭代器。insert不会失效,因为插入后返回新的节点地址,本身就指向新节点,不会失效
错误代码:
void TestListIterator1() {int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };list<int> l(array, array+sizeof(array)/sizeof(array[0]));auto it = l.begin();while (it != l.end()){// erase()函数执行后,it所指向的节点已被删除,因此it无效,在下一次使用it时,必须先给 其赋值l.erase(it); ++it;} }
改正后:
// 改正 void TestListIterator() {int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };list<int> l(array, array+sizeof(array)/sizeof(array[0]));auto it = l.begin();while (it != l.end()){l.erase(it++); // it = l.erase(it);两种写法都对} }
2. list的模拟实现
要模拟实现list,必须要熟悉list的底层结构以及其接口的含义,通过上面的学习,这些内容已基本掌握,现在我们来模拟实现list。
2.1源码
test.cpp
#include<iostream>
#include<list>
#include<vector>
#include<algorithm>
using namespace std;#include"List.h"namespace jzy
{void test_list1(){list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);list<int>::iterator it = lt.begin();while (it != lt.end()){//*it += 10;cout << *it << " ";++it;}cout << endl;for (auto e : lt){cout << e << " ";}cout << endl;}void test_list2(){list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);for (auto e : lt){cout << e << " ";}cout << endl;lt.push_back(5);lt.push_front(0);for (auto e : lt){cout << e << " ";}cout << endl;lt.pop_back();lt.pop_front();for (auto e : lt){cout << e << " ";}cout << endl;lt.clear();for (auto e : lt){cout << e << " ";}cout << endl;lt.push_back(10);lt.push_back(20);for (auto e : lt){cout << e << " ";}cout << endl;}void test_list3(){list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);for (auto e : lt){cout << e << " ";}cout << endl;list<int> copy(lt);for (auto e : copy){cout << e << " ";}cout << endl;list<int> lt1;lt1.push_back(10);lt1.push_back(20);lt1.push_back(30);lt1.push_back(40);lt = lt1;for (auto e : copy){cout << e << " ";}cout << endl;}void print_list(const list<int>& lt){list<int>::const_iterator it = lt.begin();while (it != lt.end()){//*it += 10;cout << *it << " ";++it;}cout << endl;for (auto e : lt){cout << e << " ";}cout << endl;}void test_list4(){list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);print_list(lt);list<int>::iterator it = lt.begin();while (it != lt.end()){*it += 10;cout << *it << " ";++it;}cout << endl;}struct AA{int _a1;int _a2;AA(int a1 = 1, int a2 = 1):_a1(a1), _a2(a2){}};void test_list5(){list<AA> lt;AA aa1;lt.push_back(aa1);lt.push_back(AA());AA aa2(2, 2);lt.push_back(aa2);lt.push_back(AA(2, 2));list<AA>::iterator it = lt.begin();cout << (*it)._a1 << ":" << (*it)._a2 << endl;cout << it.operator*()._a1 << ":" << it.operator*()._a2 << endl;cout << it->_a1 << ":" << it->_a2 << endl;cout << it.operator->()->_a1 << ":" << it.operator->()->_a2 << endl;cout << endl;}}int main(){jzy::test_list1();return 0;}
list.h
#pragma once
#include<assert.h>namespace jzy
{template<class T>struct ListNode{ListNode<T>* _next;ListNode<T>* _prev;T _data;ListNode(const T& x = T()):_next(nullptr), _prev(nullptr), _data(x){}};template<class T, class Ref, class Ptr>struct __list_iterator{typedef ListNode<T> Node;typedef __list_iterator<T, Ref, Ptr> self;Node* _node;__list_iterator(Node* x):_node(x){}// ++itself& operator++(){_node = _node->_next;return *this;}// it++self operator++(int){self tmp(*this);_node = _node->_next;return tmp;}self& operator--(){_node = _node->_prev;return *this;}self operator--(int){self tmp(*this);_node = _node->_prev;return tmp;}Ref operator*(){return _node->_data;}Ptr operator->(){return &_node->_data;}bool operator!=(const self& s){return _node != s._node;}bool operator==(const self& s){return _node == s._node;}};//template<class T>//struct __list_const_iterator//{// typedef ListNode<T> Node;// typedef __list_const_iterator<T> self;// Node* _node;// __list_const_iterator(Node* x)// :_node(x)// {}// // ++it// self& operator++()// {// _node = _node->_next;// return *this;// }// // it++// self operator++(int)// {// self tmp(*this);// _node = _node->_next;// return tmp;// }// self& operator--()// {// _node = _node->_prev;// return *this;// }// self operator--(int)// {// self tmp(*this);// _node = _node->_prev;// return tmp;// }// const T& operator*()// {// return _node->_data;// }// bool operator!=(const self& s)// {// return _node != s._node;// }// bool operator==(const self& s)// {// return _node == s._node;// }//};template<class T>class list{typedef ListNode<T> Node;public:typedef __list_iterator<T, T&, T*> iterator;typedef __list_iterator<T, const T&, const T*> const_iterator;iterator begin(){//return iterator(_head->_next);return _head->_next;}iterator end(){return _head;}const_iterator begin() const{return _head->_next;}const_iterator end() const{return _head;}void empty_init(){_head = new Node;_head->_next = _head;_head->_prev = _head;}list(){empty_init();}void clear(){iterator it = begin();while (it != end()){it = erase(it);}}~list(){clear();delete _head;_head = nullptr;}list(const list<T>& lt){empty_init();for (const auto& e : lt){push_back(e);}}// lt1 = lt2;// list<T>& operator=(const list<T>& lt)/*list<T>& operator=(list<T>& lt){if (this != <){clear();for (const auto& e : lt){push_back(e);}}return *this;}*/void swap(list<T>& tmp){std::swap(_head, tmp._head);}//list& operator=(list lt)list<T>& operator=(list<T> lt){swap(lt);return *this;}void push_back(const T& x){/*Node* newnode = new Node(x);Node* tail = _head->_prev;tail->_next = newnode;newnode->_prev = tail;newnode->_next = _head;_head->_prev = newnode;*/insert(end(), x);}void push_front(const T& x){insert(begin(), x);}void pop_back(){erase(--end());}void pop_front(){erase(begin());}// vector insert会导致迭代器失效// list会不会?不会iterator insert(iterator pos, const T& x){Node* cur = pos._node;Node* prev = cur->_prev;Node* newnode = new Node(x);// prev newnode curprev->_next = newnode;newnode->_prev = prev;newnode->_next = cur;cur->_prev = newnode;//return iterator(newnode);return newnode;}iterator erase(iterator pos){assert(pos != end());Node* cur = pos._node;Node* prev = cur->_prev;Node* next = cur->_next;prev->_next = next;next->_prev = prev;delete cur;return next;}private:Node* _head;};
}
注意list的const迭代器可以实现为一个类,也可以实现为模版参数实例化后的结果,一般实现为后者,会少写很多冗余代码
2.2 list的反向迭代器
ReverseIterator.h
template<class Iterator,class Ref,class Ptr> struct ReverseIterator {typedef ReverseIterator<Iterator, Ref, Ptr> Self;Iterator cur;ReverseIterator(Iterator it):cur(it){ }Self& operator++(){--cur;return *this;}Ref operator*(){Iterator tmp = cur;--tmp;return *tmp;}Ptr operator->(){return &(operator*());}bool operator!=(const Self& s){return cur != s.cur;} };
List.h
在list类内部多了一些改动,将反向迭代器的类重命名,并且新加两个成员函数
test.cpp
#define _CRT_SECURE_NO_WARNINGS 1#include<iostream> #include<list>using namespace std;#include"List.h"int main() {jzy::list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);jzy::list<int>::reverse_iterator rit = lt.rbegin();while (rit != lt.rend()){cout << *rit << " ";++rit;}cout << endl;return 0; }
可以看到反向迭代器起了作用,下面我来讲解反向迭代器的原理
反向迭代器可以理解成封装了正向迭代器,正向迭代器又封装了原生指针,反向迭代器++等价于正向迭代器--,反向迭代器解引用相当于正向迭代器--再解引用
因为反向迭代器的开始是正向迭代器结束位置,结束是正向的开始,所以反向迭代器要先--在解引用才是正确的值
反向迭代器的->也就是*拿到存放的值再取地址,和之前讲的是一个道理
typedef ReverseIterator<iterator, T&, T*> reverse_iterator;//typedef ReverseIterator<const_iterator, const T&, const T*> const_reverse_iterator;reverse_iterator rbegin(){return reverse_iterator(end());}reverse_iterator rend(){return reverse_iterator(begin());}
反向迭代器在list类那里要多加一些东西,重命名反向迭代器这个类,当是普通反向迭代器的时候实例化iterator,T&,T*,当是const反向迭代器的时候,实例化参数是const_iterator,const T&,const T*
总体来讲,可以把反向迭代器看成适配器,当实例化参数是普通迭代器,会按照普通迭代器的行为进行操作,当参数是const时,会调用const的操作
3. list与vector的对比
vector与list都是STL中非常重要的序列式容器,由于两个容器的底层结构不同,导致其特性以及应用场景不同,其主要不同如下:
list模拟实现讲解
定义结点结构体,结构体成员是前仆后继指针和元素data,还要写一个构造函数用来初始化结点
迭代器封装为一个类,类定义的对象存放每个节点的地址,也就是_node,相当于迭代器指针被封装成了一个类里存放,typedef是将类型重命名,将长的类型重命名为短的,记住类名不是类型,类名<类型>才是类型
这里模版有三个参数,第一个T是实例化类型,第二个和第三个参数是为了*和->,const类型会匹配T,constT& ,constT* ,正常类型会匹配T,T&,T*
这里将原生指针封装了一层包装在一个类里边,类定义的对象会通过操作指针前后移动来操作结点,解引用拿到对应结点的值,或者->拿到对应的地址
迭代器构造函数,当返回值是iterator类型时,会构造一个临时对象来操作
迭代器++,--,和日期类的原理类似,++it是当前指针往后走一步,this是it的地址,然后返回++之后的值,后置++,参数多传一个int就行,构造一个局部对象,指针向后走一步,返回走之前的值,迭代器--和++同理,无非是向前走
operator*是(*it)相当于拿到对应的值,我们就把it当成指针,*it当成解引用地址即可,这里是把指针封装到类里边,和前边string和vector的指针有所区分;->箭头相当于拿到存放对象的地址,当在list内部存放结构体时会用到
最简单的两个运算符重载,当判断不等于的时候会用到
list类要把上边两个类typedef后的类型写上去,方便等会用
迭代器的重载,当我们用begin()或者end()的时候,会调用这四个重载,普通对象调用普通迭代器,返回普通可修改指向对象的迭代器(这个对象可以用类名(),也可以直接返回Node*的结点指针(单参数的构造函数支持隐式类型转换),这两个写法都会生成一个临时对象,然后进行使用),const类型调用const迭代器,返回const不可修改指向对象的迭代器(慢慢理解这部分,其实没有想象的那么难)
list类的私有成员是_head,充当一个指针用来声明第一个哨兵位头结点
默认构造是初始化一个哨兵位头结点,结点内部存放前仆后继指针和data值(是某个类型的默认构造),然后让_head指向第一个哨兵位结点,并且_next和_prev都指向自己,完成哨兵位结点的初始化
析构函数先用clear清理,删除除了哨兵位结点的剩余存放有效数据的结点(释放了空间),最后释放哨兵位结点空间,_head置空就OK
拷贝构造,先初始化一个哨兵位结点,然后将要构造的对象内容依次给给e,尾插到新对象后边
赋值拷贝,先拷贝构造一个lt,将lt和新对象交换,lt是局部对象,出作用域会调用析构函数,新对象引用返回,完成赋值拷贝
insert插入,参数是迭代器指针(生成临时对象+2次拷贝构造)和要插入的值,cur指向要插入位置,prev存放要插入位置前边的指针,new一个新节点是要插入的新结点
三个指针相对位置是这样的,一般都是在某个位置之前插入,所以是这样的关系,然后按顺序链接这三个位置,前一个位置的后继指针和后一个位置的前驱指针都指向中间位置,最后返回插入节点的迭代器(单参数构造函数支持隐式类型转换)
删除很简单,不能删除哨兵位结点,找到要删除节点,记录要删除结点的前一个和后一个,链接两边的节点,最后释放要删除节点的空间,返回下一个节点的迭代器(会隐式类型转换成iterator类型的对象)
尾插,可以自己重新写逻辑,也可以复用insert逻辑,将第一个参数换成最后一个位置的迭代器,相当于在哨兵位节点之前插入,效果是一样的
头插,尾插,尾删是一样的,复用insert,erase逻辑就行
这部分在c语言实现数据结构链表那里讲的很详细了,想看的可以看看
代码样例讲解
这是一个很基础的尾插和打印对象逻辑,可以用第一个迭代器打印,也可以用第二个,范围for打印(范围for底层就是迭代器,无脑替换成迭代器进行打印),可以看到*it和it++,都是我们封装成类的功劳,原理很简单前面讲过
测试插入删除逻辑,可以看到不管是头插,头删,尾插,尾删都很清晰明了,clear是直接删除有效结点只剩哨兵位,所以打印不出来
可以看到,拷贝构造和赋值拷贝都完成了使命,前边讲的很详细,这里不再赘述
这里主要测试普通迭代器和const迭代器,各自调用各自,const迭代器不可修改对象,普通迭代器可以修改对象
最后一个样例,插入AA类对象,*it是拿到存放的结构体变量,.操作符访问结构体成员,拿到1:1,打印第二行是编译器会将*it转换成it.operator*(),效果是一样的
->箭头访问操作符会特殊处理一个箭头可以当做两个->->,并且编译器会转换成it.operator->()->_a1去访问,会特殊处理,这里当成特殊处理就好
以上就是我对list容器内容的讲解,很详细,欢迎大神交流!!!
相关文章:

list容器(详解)
1. list的介绍及使用 1.1 list的介绍(双向循环链表) https://cplusplus.com/reference/list/list/?kwlist(list文档介绍) 1. list是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭…...

Elasticsearch基本使用详解
文章目录 Elasticsearch基本使用详解一、引言二、环境搭建1、安装 Elasticsearch2、安装 Kibana(可选) 三、索引操作1、创建索引2、查看索引3、删除索引 四、数据操作1、插入数据2、查询数据(1)简单查询(2)…...

17.3.4 颜色矩阵
版权声明:本文为博主原创文章,转载请在显著位置标明本文出处以及作者网名,未经作者允许不得用于商业目的。 17.3.4.1 矩阵基本概念 矩阵(Matrix)是一个按照长方阵列排列的复数或实数集合,类似于数组。 由…...

FPGA 时钟多路复用
时钟多路复用 您可以使用并行和级联 BUFGCTRL 的组合构建时钟多路复用器。布局器基于时钟缓存 site 位置可用性查找最佳布局。 如果可能,布局器将 BUFGCTRL 布局在相邻 site 位置中以利用专用级联路径。如无法实现,则布局器将尝试将 BUFGCTRL 从…...

机器学习10
自定义数据集 使用scikit-learn中svm的包实现svm分类 代码 import numpy as np import matplotlib.pyplot as pltclass1_points np.array([[1.9, 1.2],[1.5, 2.1],[1.9, 0.5],[1.5, 0.9],[0.9, 1.2],[1.1, 1.7],[1.4, 1.1]])class2_points np.array([[3.2, 3.2],[3.7, 2.9],…...

【Block总结】CoT,上下文Transformer注意力|即插即用
一. 论文信息 标题: Contextual Transformer Networks for Visual Recognition论文链接: arXivGitHub链接: https://github.com/JDAI-CV/CoTNet 二. 创新点 上下文Transformer模块(CoT): 提出了CoT模块,能够有效利用输入键之间的上下文信息…...

linux库函数 gettimeofday() localtime的概念和使用案例
在Linux系统中,gettimeofday() 和 localtime() 是两个常用的时间处理函数,分别用于获取高精度时间戳和将时间戳转换为本地时间。以下是它们的概念和使用案例的详细说明: 1. gettimeofday() 函数 概念 功能:获取当前时间…...

编程题-电话号码的字母组合(中等)
题目: 给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。 给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。 解法一(哈希表动态添加)&#x…...

EasyExcel使用详解
文章目录 EasyExcel使用详解一、引言二、环境准备与基础配置1、添加依赖2、定义实体类 三、Excel 读取详解1、基础读取2、自定义监听器3、多 Sheet 处理 四、Excel 写入详解1、基础写入2、动态列与复杂表头3、样式与模板填充 五、总结 EasyExcel使用详解 一、引言 EasyExcel 是…...

基于“蘑菇书”的强化学习知识点(二):强化学习中基于策略(Policy-Based)和基于价值(Value-Based)方法的区别
强化学习中基于策略(Policy-Based)和基于价值(Value-Based)方法的区别 摘要强化学习中基于策略(Policy-Based)和基于价值(Value-Based)方法的区别1. 定义与核心思想(1) 基于策略的方…...

民法学学习笔记(个人向) Part.2
民法学学习笔记(个人向) Part.2 民法始终在解决两个生活中的核心问题: 私法自治;交易安全; 3. 自然人 3.4 个体工商户、农村承包经营户 都是特殊的个体经济单位; 3.4.1 个体工商户 是指在法律的允许范围内,依法经…...

物业管理系统源码驱动社区管理革新提升用户满意度与服务效率
内容概要 在当今社会,物业管理正面临着前所未有的挑战,尤其是在社区管理方面。人们对社区安全、环境卫生、设施维护等日常生活需求愈发重视,物业公司必须提升服务质量,以满足居民日益增长的期望。而物业管理系统源码的出现&#…...

租房管理系统助力数字化转型提升租赁服务质量与用户体验
内容概要 随着信息技术的快速发展,租房管理系统正逐渐成为租赁行业数字化转型的核心工具。通过全面集成资产管理、租赁管理和物业管理等功能,这种系统力求为用户提供高效便捷的服务体验。无论是工业园、产业园还是写字楼、公寓,租房管理系统…...

Ollama教程:轻松上手本地大语言模型部署
Ollama教程:轻松上手本地大语言模型部署 在大语言模型(LLM)飞速发展的今天,越来越多的开发者希望能够在本地部署和使用这些模型,以便更好地控制数据隐私和计算资源。Ollama作为一个开源工具,旨在简化大语言…...

Baklib推动数字化内容管理解决方案助力企业数字化转型
内容概要 在当今信息爆炸的时代,数字化内容管理成为企业提升效率和竞争力的关键。企业在面对大量数据时,如何高效地存储、分类与检索信息,直接关系到其经营的成败。数字化内容管理不仅限于简单的文档存储,更是整合了文档、图像、…...

DeepSeek-R1 论文. Reinforcement Learning 通过强化学习激励大型语言模型的推理能力
论文链接: [2501.12948] DeepSeek-R1: Incentivizing Reasoning Capability in LLMs via Reinforcement Learning 实在太长,自行扔到 Model 里,去翻译去提问吧。 工作原理: 主要技术,就是训练出一些专有用途小模型&…...

DOM 操作入门:HTML 元素操作与页面事件处理
DOM 操作入门:HTML 元素操作与页面事件处理 DOM 操作入门:HTML 元素操作与页面事件处理什么是 DOM?1. 如何操作 HTML 元素?1.1 使用 `document.getElementById()` 获取单个元素1.2 使用 `document.querySelector()` 和 `document.querySelectorAll()` 获取多个元素1.3 创建…...

使用 HTTP::Server::Simple 实现轻量级 HTTP 服务器
在Perl中,HTTP::Server::Simple 模块提供了一种轻量级的方式来实现HTTP服务器。该模块简单易用,适合快速开发和测试HTTP服务。本文将详细介绍如何使用 HTTP::Server::Simple 模块创建和配置一个轻量级HTTP服务器。 安装 HTTP::Server::Simple 首先&…...

C++滑动窗口技术深度解析:核心原理、高效实现与高阶应用实践
目录 一、滑动窗口的核心原理 二、滑动窗口的两种类型 1. 固定大小的窗口 2. 可变大小的窗口 三、实现细节与关键点 1. 窗口的初始化 2. 窗口的移动策略 3. 结果的更新时机 四、经典问题与代码示例 示例 1:和 ≥ target 的最短子数组(可变窗口…...

基于构件的软件开发方法
摘要: 本人在2023年1月参与广东某公司委托我司开发的“虚拟电厂”项目,主要负责整体架构设计和中间件的选型,该项目为新型电力存储、电力调度、能源交易提供一整套的软件系统,包括设备接入、负载预测、邀约竞价、用户设备调控等功能。本项目以“虚拟电厂”项目为例,讨论基…...

网站快速收录:如何设置robots.txt文件?
本文转自:百万收录网 原文链接:https://www.baiwanshoulu.com/34.html 为了网站快速收录而合理设置robots.txt文件,需要遵循一定的规则和最佳实践。robots.txt文件是一个纯文本文件,它告诉搜索引擎爬虫哪些页面可以访问ÿ…...

OpenGL学习笔记(六):Transformations 变换(变换矩阵、坐标系统、GLM库应用)
文章目录 向量变换使用GLM变换(缩放、旋转、位移)将变换矩阵传递给着色器坐标系统与MVP矩阵三维变换绘制3D立方体 & 深度测试(Z-buffer)练习1——更多立方体 现在我们已经知道了如何创建一个物体、着色、加入纹理。但它们都还…...

8.攻防世界Web_php_wrong_nginx_config
进入题目页面如下 尝试弱口令密码登录 一直显示网站建设中,尝试无果,查看源码也没有什么特别漏洞存在 用Kali中的dirsearch扫描根目录试试 命令: dirsearch -u http://61.147.171.105:53736/ -e* 登录文件便是刚才登录的界面打开robots.txt…...

【优先算法】专题——位运算
在讲解位运算之前我们来总结一下常见的位运算 一、常见的位运算 1.基础为运算 << &:有0就是0 >> |:有1就是1 ~ ^:相同为0,相异位1 /无进位相加 2.给一个数 n,确定它的二进制表示…...

qt.qpa.plugin: Could not find the Qt platform plugin “dxcb“ in ““
个人博客地址:qt.qpa.plugin: Could not find the Qt platform plugin "dxcb" in "" | 一张假钞的真实世界 我遇到的场景是,在Deepin系统终端中运行PySide应用时,没有错误提示,但在VS Code中运行时ÿ…...

1-刷力扣问题记录
25.1.19 1.size()和.length()有什么区别 2.result.push_back({nums[i], nums[left], nums[right]});为什么用大括号? 使用大括号 {} 是 C11 引入的 初始化列表 语法,它允许我们在构造或初始化对象时直接传入一组值。大括号的使用在许多情况下都能让代码…...

物联网 STM32【源代码形式-使用以太网】连接OneNet IOT从云产品开发到底层MQTT实现,APP控制 【保姆级零基础搭建】
物联网(IoT)是指通过各种信息传感器、射频识别技术、全球定位系统、红外感应器等装置与技术,实时采集并连接任何需要监控、连接、互动的物体或过程,实现对物品和过程的智能化感知、识别和管理。物联网的核心功能包括数据采集与监…...

【单层神经网络】基于MXNet的线性回归实现(底层实现)
写在前面 基于亚马逊的MXNet库本专栏是对李沐博士的《动手学深度学习》的笔记,仅用于分享个人学习思考以下是本专栏所需的环境(放进一个environment.yml,然后用conda虚拟环境统一配置即可)刚开始先从普通的寻优算法开始ÿ…...

unity中的动画混合树
为什么需要动画混合树,动画混合树有什么作用? 在Unity中,动画混合树(Animation Blend Tree)是一种用于管理和混合多个动画状态的工具,包括1D和2D两种类型,以下是其作用及使用必要性的介绍&…...

《基于deepseek R1开源大模型的电子数据取证技术发展研究》
《基于deepseek R1开源大模型的电子数据取证技术发展研究》 摘要 本文探讨了基于deepseek R1开源大模型的电子数据取证技术发展前景。随着人工智能技术的快速发展,AI大模型在电子数据取证领域的应用潜力日益凸显。本研究首先分析了电子数据取证的现状和挑战…...