C++STL(六)——list模拟
目录
- 本次所需实现的三个类
- 一、结点类的模拟实现
- 构造函数
- 二、迭代器类的模拟实现
- 为什么有迭代器类
- 迭代器类的模板参数说明
- 构造函数
- ++运算符的重载
- - -运算符的重载
- ==和!=运算符的重载
- *运算符的重载
- ->运算符的重载
- 引入模板第二个和第三个参数
- 三、list的模拟实现
- 3.1 默认成员函数
- 构造函数
- 拷贝构造函数
- 赋值运算符重载函数
- 析构函数
- 3.2 迭代器相关函数
- begin和end
- 3.3 访问容器相关函数
- front和back
- 3.4 插入、删除函数
- insert和erase
- push_back和pop_back
- push_front和pop_front
- 3.5 其他函数
- size
- clear
- empty
- swap
- 总结
本次所需实现的三个类
一、结点类的模拟实现
list类是由结点类和迭代器类组成
我们经常说list在底层实现时就是一个链表,更准确来说,list实际上是一个带头双向循环链表。
因此,我们若要实现list,则首先需要实现一个结点类。而一个结点需要存储的信息有:数据、前一个结点的地址、后一个结点的地址,于是该结点类的成员变量也就出来了(数据、前驱指针、后继指针)。
而对于该结点类的成员函数来说,我们只需实现一个构造函数即可。因为该结点类只需要根据数据来构造一个结点即可,而结点的释放则由list的析构函数来完成。
构造函数
template<class T> //由于该list可能是任何类型则使用模板类
struct list_node //存放结点成员变量
{list_node<T>* _prev;list_node<T>* _next;T _val;list_node(const T& val = T()) //缺省值初始化,T不一定是内置类型所以不能直接给0:_prev(nullptr), _next(nullptr), _val(val){}
};
注意: 若构造结点时没有传入数据,则默认以list容器所存储类型的默认构造函数所构造出来的值为传入数据。
二、迭代器类的模拟实现
引入:
list迭代器是一个自定义类型,内部成员是结点指针(内置类型),我们本身想要的就是结点指针,结点指针就可以做迭代器,它不能像原生指针(如:vector、string)一样地址是连续的而list地址不是,因为底层结构的差异,所以用一个类封装结点指针,然后重载运算符后就可以像内置类型一样访问。
为什么有迭代器类
在学习string和vector时都没有说专门要实现一个迭代器类,为什么实现list的时候就需要实现一个迭代器类呢?
因为string和vector对象都将其数据存储在了一块连续的内存空间,我们通过指针进行自增、自减以及解引用等操作,就可以对相应位置的数据进行一系列操作,因此string和vector当中的迭代器就是原生指针。
但是对于list来说,其各节点在内存中位置可能不都是连续的,大多情况下都是随机的,我们不能仅通过结点指针的自增、自减以及解引用等操作对相应结点的数据进行操作,需找到下一个结点才能访问。
迭代器的意义是让使用者可以不必关心容器的底层实现,可以用简单统一的方式对容器内的数据进行访问。
既然list的结点指针的行为不满足迭代器定义,那么我们可以对这个结点指针进行封装,对结点指针的各种运算符操作进行重载,使得我们可以用和string和vector当中的迭代器一样的方式使用list当中的迭代器。比如使用list当中的迭代器进行自增操作时,实际上执行了node = node->next语句。
list迭代器类实际上就是对结点指针进行了封装,对其各种运算符进行了重载,使得结点指针的各种行为在使用者角度看起来和普通指针一样。
迭代器类的模板参数说明
list迭代器类的模板参数列表当中有三个模板参数
template<class T, class Ref, class Ptr>
在list的模拟实现当中,我们typedef重命名了两个迭代器类型,普通迭代器和const迭代器。
typedef _list_iterator<T, T&, T*> iterator;
typedef _list_iterator<T, const T&, const T*> const_iterator;
迭代器类的模板参数列表当中的Ref和Ptr分别代表的是引用类型和指针类型。
构造函数
迭代器类实际上就是对结点指针进行了封装,其成员变量就只有一个,那就是结点指针,其构造函数直接根据所给结点指针构造一个迭代器对象。
Node* _node;__list_iterator(Node* node):_node(node)
{}
++运算符的重载
当然也分为前置和后置++
self& operator++() //返回类型还是迭代器
{_node = _node->_next; //下一个位置return *this;
}self operator++(int)
{self<T> 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;
}
==和!=运算符的重载
当使用==运算符比较两个迭代器时,实际上想知道的是这两个迭代器是否是同一个位置的迭代器,判断这两个迭代器当中的结点指针的指向是否相同即可。!=运算符则相反。
//通过结点的指针比较,两数据比较时end返回的数据具有常性要加const
bool operator!=(const self& it)
{return _node != it._node;
}
bool operator==(const self& it)
{return _node == it._node;
}
*运算符的重载
使用解引用操作符时,是想得到该位置的数据内容。因此,直接返回当前结点指针所指结点的数据即可,但是这里需要使用引用返回,因为解引用后可能需要对数据进行修改。
Ref operator*() //出了作用域还在可以引用返回
{return _node->_val; //结点指针的数据
}
->运算符的重载
有些情景下我们使用迭代器的时候可能会用到->运算符。
void test2()
{struct A{A(int a=0,int b=0):_a(a),_b(b){}int _a;int _b;};ling::list<A> lt;lt.push_back(A(1,1));lt.push_back(A(2,2));lt.push_back(A(3,3));lt.push_back(A(4,4));ling::list<A>::iterator it = lt.begin();while (it != lt.end()){//cout << *it << " "; //遍历对象是自定义类型要重载流插入才可以打印//都能实现遍历//cout << (*it)._a << " "<<(*it)._b << endl; cout << it->_a << " " << it->_b << endl;++it;}cout << endl;
}
对于->运算符的重载,我们直接返回结点当中所存储数据的地址即可
Ptr operator->()
{return &_node->_val;
}
引入模板第二个和第三个参数
如上例子:
三、list的模拟实现
3.1 默认成员函数
list是一个带头双向循环链表,在构造一个list对象时,申请一个头结点,并让其前驱指针和后继指针都指向自己
由于有时容易忘记写上显示实例化模板参数才构成类型
typedef list_node<T> node; //重命名一下
构造函数
list() //初始化构成双链表
{_head = new Node; //给头节点申请空间head->_prev = head; //前后指针指向自己head->_next = head;
}
拷贝构造函数
拷贝构造函数就是根据所给list容器,拷贝构造出一个对象。对于拷贝构造函数,先申请一个头结点,并让其前驱指针和后继指针都指向自己,然后将所给容器当中的数据,通过遍历的方式一个个尾插到新构造的容器后面。
//拷贝构造函数
list(const list<T>& lt)
{_head = new node; //申请一个头结点_head->_next = _head; //头结点的后继指针指向自己_head->_prev = _head; //头结点的前驱指针指向自己for (const auto& e : lt) //记得引用{push_back(e); //将容器lt当中的数据一个个尾插到新构造的容器后面}
}
赋值运算符重载函数
一般两种写法
//传统写法
list<T>& operator=(const list<T>& lt)
{if (this != <) //避免自己给自己赋值{clear(); //清空容器for (const auto& e : lt){push_back(e); //将容器lt当中的数据一个个尾插到链表后面}}return *this; //支持连续赋值
}//现代写法
list<T>& operator=(list<T> lt) //编译器接收右值的时候自动调用其拷贝构造函数
{swap(lt); //交换这两个对象return *this; //支持连续赋值
}
析构函数
对象进行析构时,首先调用clear函数清理容器当中的数据,然后将头结点释放,最后将头指针置空
//析构函数
~list()
{clear(); //清理容器delete _head; //释放头结点_head = nullptr; //头指针置空
}
3.2 迭代器相关函数
begin和end
begin函数返回的是第一个有效数据的迭代器,end函数返回的是最后一个有效数据的下一个位置的迭代器。
list带头双向循环链表,第一个有效数据的迭代器就是使用头结点的下一个结点的地址构造出来的迭代器,最后一个有效数据的下一个位置的迭代器就是使用头结点的地址构造出来的迭代器。(最后一个结点的下一个结点就是头结点)
//单参数的构造函数支持隐式类型转换,两种写法都可以都是生成匿名对象
iterator begin()
{return _head->_next;//return iterator(_head->_next);
}
iterator end()
{return _head;//return iterator(_head);
}
3.3 访问容器相关函数
front和back
分别用于获取第一个有效数据和最后一个有效数据,因此,实现front和back函数时,直接返回第一个有效数据和最后一个有效数据的引用即可。
T& front()
{return *begin(); //返回第一个有效数据的引用
}
T& back()
{return *(--end()); //返回最后一个有效数据的引用
}//不可修改
const T& front() const
{return *begin(); //返回第一个有效数据的const引用
}
const T& back() const
{return *(--end()); //返回最后一个有效数据的const引用
}
3.4 插入、删除函数
insert和erase
当然还是任意位置插入和删除,由于会迭代器失效所以有返回值
//插入
iterator insert(iterator pos, const T& x)
{Node* cur = pos._node;Node* prev = cur->_prev;Node* newnode = new Node(x);prev->_next = newnode;newnode->_next = cur;cur->_prev = newnode;newnode->_prev = prev;
}//删除
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;
}
有了这对增删函数就可以复用在其它增删的函数身上了
push_back和pop_back
分别对应尾插、尾删
//尾插
void push_back(const T& x)
{Node* tail = _head->prev; //找到尾Node* newnode = new Node(x); //调用结点的构造函数//更新尾结点tail->_next = newnode;newnode->_prev = tail;_head->_prev = newnode;newnode->_next = _head;//可直接复用insertinsert(end(),x);
}//尾删
void pop_back()
{erase(--end());
}
push_front和pop_front
//头插
void push_front(const T& x)
{insert(begin(), x);
}//头删
void pop_front()
{erase(begin());
}
3.5 其他函数
size
获取当前容器当中的有效数据个数,因为list是链表,所以只能通过遍历的方式逐个统计有效数据的个数。
size_t size()
{size_t sz = 0;iterator it = begin();while (it != end()){++sz;++it;}return sz;
}
clear
用于清空容器,通过遍历的方式,逐个删除结点,只保留头结点
void clear()
{iterator it = begin();while (it != end()){it = erase(it);}
}
empty
用于判断容器是否为空,直接判断该容器的begin函数和end函数所返回的迭代器,是否是同一个位置的迭代器即可。(此时说明容器当中只有一个头结点)
bool empty() const
{return begin() == end(); //判断是否只有头结点
}
swap
用于交换两个容器,list容器当中存储的实际上就只有链表的头指针,将这两个容器当中的头指针交换即可。
void swap(list<T>& lt)
{std::swap(_head, lt._head); //交换两个容器当中的头指针即可
}
总结
由于list类不一定只接收一个类型如:内置类型(int、double),自定义类型,所以三个类都使用了模板。
类名+模板参数才构成类型容易忘记,往往typedef重命名一下它们也更方便使用。
相关文章:
C++STL(六)——list模拟
目录 本次所需实现的三个类一、结点类的模拟实现构造函数 二、迭代器类的模拟实现为什么有迭代器类迭代器类的模板参数说明构造函数运算符的重载- -运算符的重载和!运算符的重载*运算符的重载->运算符的重载引入模板第二个和第三个参数 三、list的模拟实现3.1 默认成员函数构…...
Spring MVC 拦截器(Interceptor)与过滤器(Filter)的区别?
1、两者概述 拦截器(Interceptor): 只会拦截那些被 Controller 或 RestController 标注的类中的方法处理的请求,也就是那些由 Spring MVC 调度的请求。过滤器(Filter): 会拦截所有类型的 HTTP …...
MySQL查询主从同步状态
在MySQL中,监控和检查主从复制(Master-Slave replication)的状态是非常重要的,这有助于确保数据的一致性和完整性。以下是一些常用的方法,可以帮助你查询MySQL的主从数据同步状态: 1. 查看主服务器状态 首…...
docker 安装 --在线方式
第一步: #!/bin/bash sudo curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo sudo sed -i -e /mirrors.cloud.aliyuncs.com/d -e /mirrors.aliyuncs.com/d /etc/yum.repos.d/CentOS-Base.repo sudo curl -o /etc/yum.repo…...
Linux系统-centos防火墙firewalld详解
Linux系统-centos7.6 防火墙firewalld详解 1 firewalld了解 CentOS 7.6默认的防火墙管理工具是firewalld,它取代了之前的iptables防火墙。firewalld属于典型的包过滤防火墙或称之为网络层防火墙,与iptables一样,都是用来管理防火墙的工具&a…...
物联网软件开发与应用方向应该怎样学习,学习哪些内容,就业方向是怎样?(文末领取整套学习视频,课件)物联网硬件开发与嵌入式系统
随着物联网技术的飞速发展,物联网软件开发与应用方向成为了众多开发者关注的焦点。那么,如何在这个领域中脱颖而出呢?本文将为你提供一份详细的学习指南,帮助你从零开始,逐步掌握物联网软件开发与应用的核心技能。 一…...
【大模型】DeepSeek与chatGPT的区别以及自身的优势
目录 一、前言二、核心技术对比2.1 模型架构设计2.1.1 ChatGPT的Transformer架构2.1.2 DeepSeek的混合架构 2.2 训练数据体系2.2.1 ChatGPT的数据特征2.2.2 DeepSeek的数据策略 三、应用场景对比3.1 通用场景表现3.1.1 ChatGPT的强项领域3.2.2 DeepSeek的专项突破 3.3 响应效率…...
常用的python库-安装与使用
常用的python库函数 yield关键字openslide库openslide库的安装-linuxopenslide的使用openslide对象的常用属性 cv2库numpy库ASAP库-multiresolutionimageinterface库ASAP库的安装ASAP库的使用 concurrent.futures.ThreadPoolExecutorxml.etree.ElementTree库skimage库PIL.Image…...
qt widget和qml界面集成到一起
将 Qt Widgets 和 QML 界面集成在一起可以利用 QQuickWidget 或 QQuickView。以下是基本步骤: 使用 QQuickWidget 创建 Qt Widgets 项目: 创建一个基于 Widgets 的应用程序。添加 QQuickWidget: 在你的窗口或布局中添加 QQuickWidget。 例如,可以在 QMainWindow 中使用: …...
mybatis 是否支持延迟加载?延迟加载的原理是什么?
1. MyBatis 是否支持延迟加载? 是的,MyBatis 支持延迟加载。延迟加载的主要功能是推迟数据加载的时机,直到真正需要时再去加载。这种方式能提高性能,尤其是在处理关系型数据时,可以避免不必要的数据库查询。 具体来说…...
MariaDB MaxScale实现mysql8主从同步读写分离
一、MaxScale基本介绍 MaxScale是maridb开发的一个mysql数据中间件,其配置简单,能够实现读写分离,并且可以根据主从状态实现写库的自动切换,对多个从服务器能实现负载均衡。 二、MaxScale实验环境 中间件192.168.121.51MaxScale…...
【图片转换PDF】多个文件夹里图片逐个批量转换成多个pdf软件,子文件夹单独合并转换,子文件夹单独批量转换,基于Py的解决方案
建筑设计公司在项目执行过程中,会产生大量的设计图纸、效果图、实景照片等图片资料。这些资料按照项目名称、阶段、专业等维度存放在多个文件夹和子文件夹中。 操作需求:为了方便内部管理和向客户交付完整的设计方案,公司需要将每个项目文件…...
基于logback+fastjson实现日志脱敏
一、需求背景 日常工作中,必不可免的会将一些敏感信息,如用户名、密码、手机号、身份证号、银行账号等等打印出来,但往往为了安全,这些信息都需要进行脱敏。脱敏实际就是用一些特殊字符来替换部分值。 JSON 和 JSONObject Fastj…...
13.10 统一配置管理中心:TranslationChain 架构的简洁配置管理方案
统一配置管理中心:TranslationChain 架构的简洁配置管理方案 1. 集中式配置文件设计 config/settings.yaml: # 多环境配置开关 env: production # development|test|production# 模型管理中心 models:openai:class: langchain_openai.ChatOpenAIparams...
deepseek大模型集成到idea
1 下载插件 安装CodeGPT打开 IntelliJ IDEA,鼠标点击左上角导航栏,File --> Setting 2 申请API key 3 配置deepseek 在 Settings 界面中的搜索框中,搜索 CodeGPT,路径 Tools --> CodeGPT --> Providers --> 如下一…...
Cocos2d-x 游戏开发-打包apk被默认自带了很多不必要的权限导致apk被报毒,如何在Cocos 2d-x中强制去掉不必要的权限-优雅草卓伊凡
Cocos2d-x 游戏开发-打包apk被默认自带了很多不必要的权限导致apk被报毒,如何在Cocos 2d-x中强制去掉不必要的权限-优雅草卓伊凡 实战操作 去除权限 要在 Cocos2d-x 开发的游戏中去掉 APK 自带权限,可以按照以下步骤操作: 编辑 AndroidMa…...
gitlab多项目流水线
背景是我有多个项目,希望其中一个项目被触发的时候,联动另外一个项目自动打包。然后我就看文档尝试操作了一下,所以有本文。 官方文档参考:https://gitlab.cn/docs/14.5/jh/ci/pipelines/multi_project_pipelines.html 不知道是不…...
GWO优化决策树回归预测matlab
灰狼优化算法(Grey Wolf Optimizer,简称 GWO)是一种群智能优化算法,由澳大利亚格里菲斯大学的 Mirjalii 等人于 2014 年提出。该算法的设计灵感源自灰狼群体的捕食行为,核心思想是模仿灰狼社会的结构与行为模式。 在本…...
2025影视泛目录站群程序设计_源码二次开发新版本无缓存刷新不变实现原理
1. 引言 本设站群程序计书旨在详细阐述苹果CMS泛目录的创新设计与实现,介绍无缓存刷新技术、数据统一化、局部URL控制及性能优化等核心功能,以提升网站访问速度和用户体验。 2. 技术概述 2.1 无缓存刷新技术 功能特点: 内容不变性&#x…...
在Linux上创建虚拟网卡
在 Linux 上创建虚拟网卡可以通过多种方式进行,常见的方式是使用 ip 命令来配置虚拟网卡。以下是一个简单的步骤指南,用于创建虚拟网卡: 步骤 1: 查看现有的网络接口 首先,查看当前网络接口的状态,可以使用以下命令&…...
JVM 类加载子系统在干什么?
JVM 类加载子系统是什么? 类加载子系统(Class Loader Subsystem)是 JVM 负责 加载、链接和初始化 .class 文件的组件。它的主要作用是将字节码文件加载进 JVM 并准备执行。 类加载器(ClassLoader)是 字节码的搬运工&…...
STM32的HAL库开发---高级定时器---互补输出带死区实验
一、互补输出简介 互补输出:OCx输出高电平,则互补通道OCxN输出低电平。OCx输出低电平,则互补通道OCxN输出高电平。 带死区控制的互补输出:OCx输出高电平时,则互补通道OCxN过一会再输出输出低电平。这个时间里输出的电…...
AntDesign X 报错:Cannot read properties of undefined (reading ‘_context‘)
解决: Cannot read properties of undefined (reading _context) 报错问题 我是基于umi的前端工程,react版本18.2, package.json,全部安装完之后的 "react": "^18.2.0", "ant-design/x": "^1…...
Day62_补20250210_图论part6_108冗余连接|109.冗余连接II
Day62_20250210_图论part6_108冗余连接|109.冗余连接II 108冗余连接 【把题意转化为并查集问题】 题目 有一个图,它是一棵树,他是拥有 n 个节点(节点编号1到n)和 n - 1 条边的连通无环无向图(其实就是一个线形图&am…...
06排序 + 查找(D2_查找(D1_基础学习))
目录 温故而知新 -------------------------------- 讲解一:基础理论 一、什么是查找 二、为什么需要查找 -------------------------------- 讲解二:代码学习 一、顺序查找 1. 算法原理 2. 算法步骤 3. Java代码实现 4. 适用场景 5. 知识小…...
SystemVerilog基础:disable fork语句
相关阅读 SystemVerilog基础https://blog.csdn.net/weixin_45791458/category_12517449.html?spm1001.2014.3001.5482 一、进程的概念 在学习disable fork语句之前,首先的了解SystemVerilog中的进程概念:进程是一系列可以独立执行的一个或多个表达式。…...
基于钉钉API的连接器实现:企业数据集成与自动化管理
文章目录 概要背景与需求钉钉API概述连接器实现小结 概要 在当今数字化时代,企业面临着海量数据的管理与整合挑战。钉钉作为国内广泛使用的办公协作平台,提供了丰富的API接口,支持企业进行数据集成与自动化管理。本文将介绍如何通过钉钉API实…...
windows server独立部署Qwen2.5-vl-7B
服务器配置信息 CPU:64G GPU:48G(RTX 4090) 一、使用conda下载模型 Qwen2.5-VL-7B-Instruct conda下载 conda create --name qwen python3.11 conda activate qwen 魔塔社区下载模型 pip install modelscope modelscope downl…...
nginx安装并部署前端项目【包括Linux与Windows系统】
nginx安装并部署前端项目 一、 nginx下载与安装二、 前端项目部署三、 常用命令&注意事项四、 常见问题【持续更新】 一、 nginx下载与安装 ① 下载地址:https://nginx.org/en/download.html ② 下载教程:根据不同操作系统(Linux或者Wi…...
pytest生成报告no tests ran in 0.01s
除了基本的环境配置、用例名要以test_开头,有个地方是我自己忽略了,在执行时没有指定用例文件,所以没有找到。 if __name__ __main__:pytest.main(["testcases/test_demo.py","-svq", __file__, --alluredir./allure-r…...
前后端服务配置
1、安装虚拟机(VirtualBox或者vmware),在虚拟机上配置centos(选择你需要的Linux版本),配置如nginx服务器等 1.1 VMware 下载路径Sign In注册下载 1.2 VirtualBox 下载路径https://www.virtualbox.org/wiki/Downloads 2、配置服…...
一文学会:用DeepSeek R1/V3 + AnythingLLM + Ollama 打造本地化部署的个人/企业知识库,无须担心数据上传云端的泄露问题
文章目录 前言一、AnythingLLM 简介&基础应用1.主要特性2.下载与安装3.配置 LLM 提供商4.AnythingLLM 工作区&对话 二、AnythingLLM 进阶应用:知识增强使用三、AnythingLLM 的 API 访问四、小结1.聊天模式2.本地存储&向量数据库 前言 如果你不知道Olla…...
[学习笔记] Kotlin Compose-Multiplatform
Compose-Multiplatform 原文:https://github.com/zimoyin/StudyNotes-master/blob/master/compose-multiplatform/compose.md Compose Multiplatform 是 JetBrains 为桌面平台(macOS,Linux,Windows)和Web编写Kotlin UI…...
202406 青少年软件编程等级考试C/C++ 三级真题答案及解析(电子学会)
第 1 题 谷歌的招聘 2004年7月,谷歌在硅谷的101号公路边竖立了一块巨大的广告牌用于招聘。内容超级简单,就是一个以.com 结尾的网址,而前面的网址是一个 10位素数,这个素数是自然常数e中最早出现的 10 位连续数字。能找出这个素数的人,就可以通过访问谷歌的这个网站进入…...
如何在Vue中实现事件处理
在Vue中,事件处理是一个核心概念,它让我们能够响应用户的操作,比如点击按钮、输入文本等。Vue提供了一个简洁而强大的方式来绑定事件和处理事件。本文将介绍如何在Vue中实现事件处理,覆盖事件绑定、事件修饰符以及事件处理函数等内…...
从零到一:基于Rook构建云原生Ceph存储的全面指南(下)
接上篇:《从零到一:基于Rook构建云原生Ceph存储的全面指南(上)》 链接: link 六.Rook部署云原生CephFS文件系统 6.1 部署cephfs storageclass cephfs文件系统与RBD服务类似,要想在kubernetes pod里使用cephfs&#…...
结合实际讲NR系列2—— SIB1
这是在基站抓取的sib1的一条信令 L3MessageContent BCCH-DL-SCH-Messagemessagec1systemInformationBlockType1cellSelectionInfoq-RxLevMin: -64q-QualMin: -19cellAccessRelatedInfoplmn-IdentityListPLMN-IdentityInfoplmn-IdentityListPLMN-IdentitymccMCC-MNC-Digit: 4MC…...
git rebase 和 git merge的区别
Rebase 可使提交树变得很干净, 所有的提交都在一条线上。 Merge 则是包含所有的调试记录,合并之后,父级的所有信息都会合并在一起 Rebase 修改了提交树的历史 比如, 提交 C1 可以被 rebase 到 C3 之后。这看起来 C1 中的工作是在 C3 之后进行的…...
JavaScript字符串类型详解
目录 一、创建字符串 1. 字面量方式 2. 使用 String 构造函数 二、字符串的不可变性 三、字符串的长度与索引 四、字符串的拼接 1. 使用加号 () 2. 使用模板字符串(ES6) 五、字符串的常用方法 1. 获取子串 substring(start, end) slice(start…...
Hdoop之MapReduce的原理
简单版本 AppMaster: 整个Job任务的核心协调工具 MapTask: 主要用于Map任务的执行 ReduceTask: 主要用于Reduce任务的执行 一个任务提交Job --> AppMaster(项目经理)--> 根据切片的数量统计出需要多少个MapTask任务 --> 向ResourceManager(Yarn平台的老大)索要资源 --…...
数据仓库和商务智能:洞察数据,驱动决策
在数据管理的众多领域中,数据仓库和商务智能(BI)是将数据转化为洞察力、支持决策制定的关键环节。它们通过整合、存储和分析数据,帮助组织更好地理解业务运营,预测市场趋势,从而制定出更明智的战略。今天&a…...
可视化工作流编排参数配置完整方案设计文档
一、背景及需求分析 1. 背景 在复杂的工作流程中,后续程序需要动态构造输入参数,这些参数源自多个前序程序的 JSON 数据输出。为了增强系统的灵活性和可扩展性,配置文件需要支持以下功能: 灵活映射前序程序的 JSON 数据。…...
Linux sysfs虚拟文件系统
文章目录 简介sysfs接口sysfs和procfs参考 本文拟对Linux sysfs虚拟文件系统进行简单的介绍和原理分析 简介 测试环境:Linux dev-PC 5.18.17-amd64-desktop-hwe #20.01.00.10 SMP PREEMPT_DYNAMIC Thu Jun 15 16:17:50 CST 2023 x86_64 GNU/Linux sysfs虚拟文件系统…...
C++ 设计模式 - 访问者模式
一:概述 访问者模式将作用于对象层次结构的操作封装为一个对象,并使其能够在不修改对象层次结构的情况下定义新的操作。 《设计模式:可复用面向对象软件的基础》一书中的访问者模式因两个原因而具有传奇色彩:一是因为它的复杂性&a…...
微软编程之C#如何学习,C#学习路线:从入门到精通
引言 C# 是一种由微软开发的面向对象编程语言,广泛应用于 Windows 应用程序开发、游戏开发(Unity)、Web 开发(ASP.NET)等领域。对于初学者来说,掌握 C# 不仅能够打开编程世界的大门,还能为未来…...
PromptSource官方文档翻译
目录 核心概念解析 提示模板(Prompt Template) P3数据集 安装指南 基础安装(仅使用提示) 开发环境安装(需创建提示) API使用详解 基本用法 子数据集处理 批量操作 提示创建流程 Web界面操作 手…...
深入理解QT的View-Model-Delegate机制和用法
文章目录 Model-View-Delegate机制Model(数据模型)设置模型属性访问元素操作元素数据排序封装好的模型View(视图)显示数据数据选择Delegate(代理)数据选择易用封装类QListWidgetQTreeWidgetQTableWidget元素拖拽代理模型参考示例Model-View-Delegate机制 Qt的View/Model/Deleg…...
【JavaScript】JavaScript 运行原理
执行上下文 JavaScript引擎会在执行代码之前,会在堆内存中创建一个全局对像:Global Object(GO) 该对象所有的作用域(scope)都可以访问,在浏览器中这个对象就是window;里面会包含Date、Array、StringNumber、setTimeout、setInte…...
力扣hot100刷题第一天
哈希 1. 两数之和 题目 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。 你可以假设每种输入只会对应一个答案,并且你不能使用两次相同的元素。你可以按任意…...
数据结构-find()-判断字符串s1中是否包含字符串s2
find()库函数 #include <iostream> using namespace std;bool check(string s1,string s2){int n s1.size();int m s2.size();if(n0||m0 || n<m){return false;}if(s1.find(s2) ! string::npos){return true;}else{return false;} }int main () {string a "…...