C++ vector 核心功能解析与实现
目录
整体结构概述
赋值运算符重载
下标运算符重载
内存管理函数
元素访问函数
插入和删除操作
完整代码
在C++标准库中, vector 是一个非常常用的动态数组容器,它能够自动管理内存,并且提供了丰富的操作接口。本文将通过分析一段手写 vector 的核心代码,深入理解 vector 的底层实现原理。
整体结构概述
我们实现的 vector 类模板主要包含以下几个关键部分:
1. 数据成员:用于管理动态数组的内存和元素范围。
2. 赋值运算符重载:实现对象之间的赋值操作。
3. 下标运算符重载:支持通过 [] 访问元素。
4. 内存管理函数: reserve 和 resize 用于控制动态数组的容量和大小。
5. 元素访问函数: front 和 back 用于获取容器的首元素和尾元素。
6. 插入和删除操作: push_back 、 pop_back 、 insert 和 erase 用于元素的增删。
cpptemplate <typename T>class vector {private:iterator _start; // 指向动态数组起始位置iterator _finish; // 指向最后一个有效元素的下一个位置iterator _end_of_storage; // 指向动态数组容量的末尾位置public:typesdef T* iterator;typesdef const T* const_iterator;// 以下是具体成员函数的实现};
赋值运算符重载
cppvector<T>& operator=(vector<T>& v) {swap(v);return *this;}
现代化写法
该函数实现了 vector 对象之间的赋值操作。通过调用 swap 函数交换当前对象和传入对象的内部数据( _start 、 _finish 和 _end_of_storage ),从而高效地完成赋值。 swap 函数的具体实现通常会交换两个对象的资源,而不是逐个复制元素,这样可以提高效率。
下标运算符重载
cppT& operator[](size_t pos) {assert(pos < size());return _start[pos];}const T& operator[](size_t pos) const {assert(pos < size());return _start[pos];}
这两个函数实现了通过 [] 操作符访问 vector 中的元素。第一个函数是非 const 版本,用于修改元素;第二个函数是 const 版本,用于在 const vector 对象上读取元素。通过 assert 确保访问的下标在有效范围内,防止越界访问。
内存管理函数
reserve 函数
void reserve(size_t n){if (n > capacity()){size_t sz = size();t* tmp = new t[n];if (_start){//memcpy(_tmp,_start,sizeof(T)*sz);for (size_t i = 0;i < sz;i++){tmp[i] = _start[i];}delete[]_start;}_start = tmp;_finish = _start + sz;_end_of_storage = _start + n;}}
reserve 函数用于确保 vector 的容量至少为 n 。如果 n 大于当前容量,会分配一块新的更大的内存,将原有的元素逐个复制到新内存中,然后释放旧内存,并更新 _start 、 _finish 和 _end_of_storage 指针。
resize 函数
cppvoid resize(size_t n, const T& val = T()) {if (n < size()) {_finish = _start + n;} else {reserve(n);while (_finish != _start + n) {*_finish = val;++_finish;}}}
resize 函数用于改变 vector 的大小。如果 n 小于当前大小,会截断 vector ;如果 n 大于当前大小,会先调用 reserve 确保有足够的容量,然后将新增位置初始化为 val 。
元素访问函数
front 函数
cppT& front() {return *_start;}const T& front() const {return *_start;}
front 函数用于获取 vector 的首元素。非 const 版本允许修改首元素, const 版本则用于在 const vector 对象上获取首元素。
back 函数
cppT& back() {return *(_finish - 1);}const T& back() const {return *(_finish - 1);}
back 函数用于获取 vector 的尾元素。同样分为非 const 和 const 版本,分别用于修改和读取尾元素。
插入和删除操作
push_back 函数
cppvoid push_back(const T& x) {insert(end(), x);}
push_back 函数在 vector 的末尾插入一个元素,它通过调用 insert 函数实现。
pop_back 函数
cppvoid pop_back() {erase(end() - 1);}
pop_back 函数删除 vector 的尾元素,通过调用 erase 函数实现。
erase 函数
cppiterator erase(iterator pos) {iterator begin = pos + 1;while (begin != _finish) {*(begin - 1) = *begin;++begin;}_finish--;return pos;}
erase 函数删除指定位置的元素。通过将该位置之后的元素逐个向前移动,覆盖要删除的元素,然后更新 _finish 指针。
insert 函数
cppiterator insert(iterator pos, const T& x) {assert(pos <= _finish);if (_finish == _end_of_storage) {size_t len = pos - _start;size_t new_cap = (capacity() == 0) ? 4 : capacity() * 2;reserve(new_cap);pos = _start + len;}iterator end = _finish - 1;while (end >= pos) {*(end + 1) = *end;end--;}*pos = x;_finish++;return pos;}
insert 函数在指定位置插入一个元素。如果当前容量已满,会先调用 reserve 扩大容量,然后将插入位置之后的元素逐个向后移动,腾出空间插入新元素,并更新 _finish 指针。
通过以上代码的实现,我们可以对 vector 的核心功能有一个更深入的理解,掌握动态数组的内存管理和元素操作的底层原理。在实际开发中,合理使用 vector 可以提高代码的效率和可读性。
完整代码
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
#include<assert.h>
namespace ldg
{template<class T>class vecctor{public://原生指针typedef T* iterator;typedef const T* const_iterator;size_t size() {return _finish - _start;}size_t capacity(){return _end_of_storage - _start;}bool empty()const {return _start == _finish;}iterator begin(){return _start;}iterator cend(){return _finish;}const_iterator cbegin()const{return _start;}const_iterator cend()const{return _finish;}//构造和销毁vector():_start(nullptr), _finish(nullptr), _end_of_storage(nullptr){}vector(size_t n,const T& val=T()):_start(nullptr), _finish(nullptr), _end_of_storage(nullptr){reserve(n);while (n--) push_back(val);}vector(int n, const T& val = T()):_start(new T[n]), _finish(_start+n), _end_of_storage(_finish){for (int i = 0;i < n;i++)_start[i] = val;}template <class Inititerator>vector(Inititerator first, Inititerator last){while (first != last){push_back(*first);first++;}}//vector(const vector<T>& v)// :_start(nullptr)// , _finish(nullptr)// , _end_of_storage(nullptr)//{// _start = new T[v.capacity()];// //memccpy(_start,v._start,sizeof(T)*v.size());// for (size_t i = 0;i < size();i++)// {// _start[i] = v._start[i];// }// _finish = _start + v.size();// _ens_of_storage = _start + v.capacity();//}vector(const vector<T>& v):_start(nullptr), _finish(nullptr), _end_of_storage(nullptr){reserve(v.capacity());for (auto e : v)push_back(e);}~vector(){if (_start) {delete[]_start;_start = _finish = _end_of_storage = nullptr;}}void swap(vector<T>& v){std::swap(_start, v._start);std::swap(_finish, v._finish);std::swap(_ens_of_storage, v._ens_of_storage);}vector<T>& operator=(vector<T>& v){swap(v);return *this;}T& operator[](size_t pos){assert(pos < size());return _start[pos];}const T& operator[](size_t pos)const{assert(pos < size());return _start[pos];}void reserve(size_t n){if (n > capacity()){size_t sz = size();t* tmp = new t[n];if (_start){//memcpy(_tmp,_start,sizeof(T)*sz);for (size_t i = 0;i < sz;i++){tmp[i] = _start[i];}delete[]_start;}_start = tmp;_finish = _start + sz;_end_of_storage = _start + n;}}void resize(size_t n, const T& val = T()){if (n < size()){_finish = _start + n;}else{reserve(n);while (_finish != _start + n){*finish = val;++_finish;}}}T& front(){return *_start;}const T& front()const{return *_start;}T& back(){return *(finish-1);}const T& back()const{return *(finish - 1);}void push_back(const T& x){insert(end(), x);}void pop_back(){ease(end() - 1);}//pos位置插入x//删除pos位置,返回pos+1iterator erase(iterator pos){iterator begin = pos + 1;while (begin = _finish){*(begin - 1) = *begin;++begin;}_finish--;return pos;}iterator insert(iterator pos, const T& x){assert(pos <= finish);if (_finish == _end_of_storage){size_t len = pos-start;size_t newst = (capacity() == 0) ? 4 : capacity() * 2;reserve(newst);pos = _start + len;//防止迭代器失效}iterator end = _finish - 1;while (end >= pos){*(end + 1) = *end;end--;}*pos = x;finish--;return pos;//防止迭代器失效}private:iterator _start;iterator _finish;iterator _end_of_storage;};
相关文章:
C++ vector 核心功能解析与实现
目录 整体结构概述 赋值运算符重载 下标运算符重载 内存管理函数 元素访问函数 插入和删除操作 完整代码 在C标准库中, vector 是一个非常常用的动态数组容器,它能够自动管理内存,并且提供了丰富的操作接口。本文将通过分析一段手写 …...
【Linux网络】构建UDP服务器与字典翻译系统
📢博客主页:https://blog.csdn.net/2301_779549673 📢博客仓库:https://gitee.com/JohnKingW/linux_test/tree/master/lesson 📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正! &…...
DeepSeek 大模型 + LlamaIndex + MySQL 数据库 + 知识文档 实现简单 RAG 系统
DeepSeek 大模型 LlamaIndex MySQL 数据库 知识文档 实现简单 RAG 系统 以下是一个使用 DeepSeek 大模型(假设为一个高性能的中文大模型)、LlamaIndex、MySQL 数据库 和 知识文档 实现简单 RAG(检索增强生成)系统的完整示例。该…...
【FFmpeg从入门到精通】第四章-FFmpeg转码
1 FFmpeg 软编码H.264与H.265 当前网络中常见的视频编码格式要数H.264最为火热,支持H.264的封装格式有很多,如FLV、MP4、HLS(M3U8)、MKV、TS等格式;FFmpeg本身并不支持H.264的编码器,而是由FFmpeg的第三方模块对其进行支持,例如x…...
爱普生RX8130CE实时时钟成为智能家居系统的理想解决方案
智能家居的本质是让生活更便捷、舒适与智能,而精准的时间管理是实现这一目标的重要基础。爱普生 RX8130CE 实时时钟(RTC)以其卓越的性能和丰富的功能,成为智能家居系统的理想时间解决方案,为用户打造更加智能化、人性化…...
Discuz!与DeepSeek的深度融合:打造智能网址导航新标杆
引言 在数字化信息爆炸的时代,网址导航网站作为用户获取优质资源、高效浏览互联网的重要入口,其信息筛选能力、用户体验和商业化潜力成为了决定其竞争力的核心要素。Discuz!作为国内应用广泛的社区论坛系统,以其强大的功能扩展性和用户管理能…...
23种设计模式-结构型模式之代理模式(Java版本)
Java 代理模式(Proxy Pattern)详解 🧭 什么是代理模式? 代理模式是结构型设计模式之一,为其他对象提供一个代理以控制对这个对象的访问。 就像生活中的“经纪人”,你无法直接联系明星,但可以…...
网络不可达network unreachable问题解决过程
问题:访问一个环境中的路由器172.16.1.1,发现ssh无法访问,ping发现回网络不可达 C:\Windows\System32>ping 172.16.1.1 正在 Ping 172.16.1.1 具有 32 字节的数据: 来自 172.16.81.1 的回复: 无法访问目标网。 来自 172.16.81.1 的回复:…...
@RefreshScope 和@nacosvalue 的区别
文章目录 1. RefreshScope定义与作用工作原理适用场景示例代码 2. NacosValue定义与作用工作原理适用场景示例代码 3. 主要区别4. 如何选择?5. 注意事项 在 Spring 框架中, RefreshScope 和 NacosValue 是两个不同的注解,分别用于不同的场景…...
Oracle EBS R12.2 安装 -- Step by Step
一、引言 在计算机应用已经非常普及的今天,对于绝大部分个人来说,学习并掌握ORACLE ERP系统是一件“实践性”很强的事情,仅仅“纸上谈兵”而不在系统中进行具体的操作,犹如捧着一本“驾驶手册”苦读,但却没有一辆车进行上路演练,是肯定无法学会开车的道理一样,能够为自…...
【JavaEE】计算机的工作原理
计算机系统的组成 一台完整的计算机包含硬件和软件两部分,另外还有一部分固化的软件称为固件(兼具软件和硬件的特性),硬件和软件结合才能使计算机正常运行并发挥作用,所以对计算机的理解应该把它看作一个包含软件系统…...
DAY8:Oracle高可用架构深度解析与Data Guard单节点搭建实战
引言 在数据库领域,高可用性(High Availability)是保障业务连续性的核心要求。Oracle作为企业级数据库的领导者,提供了RAC、Data Guard、GoldenGate三大核心方案。本文将深入剖析这些技术的实现原理,并手把手指导搭建…...
程序的编译(预处理操作)+链接
程序的编译环境和执行环境 翻译环境:在这个环境中源代码被转换成可执行的机器指令 执行环境:用于实际执行代码 详解编译链接 翻译环境 注意: 1.组成一个程序的每个源文件通过编译过程分别转换成目标代码。 2.每个目标文件由链接器捆绑在一…...
Java 实现桌面共享-简单案例
服务器端(共享桌面) import java.awt.AWTException; import java.awt.Rectangle; import java.awt.Robot; import java.awt.Toolkit; import java.awt.image.BufferedImage; import java.io.DataOutputStream; import java.io.IOException; import java…...
Idea中实用设置和插件
目录 一、Idea使用插件 1.Fitten Code智能提示 2.MyBatisCodeHelperPro 3.HighlightBracketPair 4.Rainbow Brackets Lite 5.GitToolBox(存在付费) 6.MavenHelperPro 7.Search In Repository 8.VisualGC(存在付费) 9.vo2dto 10.Key Promoter X 11.CodeGlance…...
获取电脑信息(登录电脑的进程、C盘文件信息、浏览器信息、IP)
电脑的进程信息 // 获取登录电脑的进程信息String os System.getProperty("os.name").toLowerCase();String command;if (os.contains("win")) {command "tasklist";} else {command "ps -ef";}try {Process process new ProcessB…...
单例模式(线程安全)
1.什么是单例模式 单例模式(Singleton Pattern)是一种创建型设计模式,旨在确保一个类只有一个实例,并提供一个全局访问点来访问该实例。这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单…...
Sentinel源码—7.参数限流和注解的实现二
大纲 1.参数限流的原理和源码 2.SentinelResource注解的使用和实现 2.SentinelResource注解的使用和实现 (1)SentinelResource注解的使用 (2)SentinelResource注解和实现 (1)SentinelResource注解的使用 一.引入Sentinel Spring Boot Starter依赖 <dependency><…...
【单片机 C语言】单片机学习过程中常见C库函数(学习笔记)
memset() C 标准库 - <string.h> string .h 头文件定义了一个变量类型、一个宏和各种操作字符数组的函数。 <string.h> 是 C 标准库中的一个头文件,提供了一组用于处理字符串和内存块的函数。这些函数涵盖了字符串复制、连接、比较、搜索和内存操作…...
聚类算法(K-means、DBSCAN)
聚类算法 K-means 算法 算法原理 K-means 是一种基于类内距离最小化的划分式聚类算法,其核心思想是通过迭代优化将数据划分为 K 个簇。目标函数为最小化平方误差(SSE): S S E ∑ i 1 K ∑ x ∈ C i ∣ ∣ x − μ i ∣ ∣ 2…...
Spring AI Alibaba Graph基于 ReAct Agent 的天气预报查询系统
1、在本示例中,我们仅为 Agent 绑定了一个天气查询服务,接收到用户的天气查询服务后,流程会在 AgentNode 和 ToolNode 之间循环执行,直到完成用户指令。示例中判断指令完成的条件(即 ReAct 结束条件)也很简…...
C++初阶——模板
C初阶——模板 一、概念引入 1.如何实现一个通用的交换函数,使它既可以用来交换各种类型的数据呢? 通过前面的学习,我们知道函数重载可以帮我们实现这一功能,代码如下: 运行结果如图: 使用函数重载虽然…...
【技术派后端篇】技术派中基于 Redis 的缓存实践
在互联网应用追求高并发和高可用的背景下,缓存对于提升程序性能至关重要。相较于本地缓存 Guava Cache 和 Caffeine,Redis 具有显著优势。Redis 支持集群和分布式部署,能横向扩展缓存容量和负载能力,适应大型分布式系统的缓存需求…...
系统安装及应用
重点 账号安全控制 系统引导和登陆控制 弱口令检测 端口扫描 前言 随着信息技术的快速发展,系统安全成为我们日常生活和工作中不可或缺的一部分。本章节主要探讨系统安全及应用,涵盖了账号安全控制、系统引导和登录控制、弱口令检测以及端口扫描等多个方面,为我们提供了一…...
发布事件和Insert数据库先后顺序
代码解释 csharp await PublishCreatedAsync(entity).ConfigureAwait(false); await Repository.InsertAsync(entity).ConfigureAwait(false);PublishCreatedAsync(entity):这是一个异步方法,其功能是发布与实体创建相关的事件。此方法或许会通知其他组…...
【英语语法】词法---冠词
目录 冠词一、不定冠词:a / an1. 基本用法2. 主要使用场景3. 特殊情况 二、定冠词:the1. 基本用法2. 主要使用场景3. 特殊情况 三、零冠词1. 基本规则2. 特殊情况 四、冠词对比五、常见错误总结 冠词 冠词是英语中用于限定名词的一类虚词,分…...
android的 framework 有哪些知识点和应用场景
Android Framework 知识点 1. 四大组件 Activity(活动) 是 Android 应用中最基本的组件,用于实现用户界面。一个 Activity 通常对应一个屏幕的内容。有自己的生命周期,包括 onCreate、onStart、onResume、onPause、onStop、onDe…...
Prompt 攻击与防范:大语言模型安全的新挑战
随着大语言模型(LLM)在企业服务、智能助手、搜索增强等领域的广泛应用,围绕其"Prompt"机制的安全问题也逐渐引起关注。其中最具代表性的,就是所谓的 Prompt Injection(提示词注入)攻击。 本文将…...
Ubuntu20.04安装Pangolin遇到的几种报错的解决方案
1.添加两个编译选项 /usr/include/OpenEXR/half.h:121:13: note: because ‘half’ has user-provided ‘half& half::operator(half)’121 | half & operator (half h);| ^~~~~~~~ 解决方案: 在CMakeList中添加以下两句: …...
软考 中级软件设计师 考点知识点笔记总结 day14 关系代数 数据库完整性约束
文章目录 6.5 关系代数6.5.1 关系代数—七种基本运算 6.6 数据库完整性约束6.7 关系型数据库SQL简介 6.5 关系代数 候选码(键):若关系中的某一属性或属性组的值能唯一标识一个元组,则称该属性或属性组为候选码。 主码࿰…...
前端vue监听 -watch
前端vue监听 -watch 前言基本用法监听简单数据属性监听对象属性 高级用法深度监听对象即时触发监听监听计算属性 注意事项 前言 在 Vue.js 里,watch 选项可用于响应式地监听数据的变化,当被监听的数据发生改变时,就会触发相应的回调函数来执…...
Linux之信号
目录 一、预备知识 二、信号的产生 一、键盘产生信号 二、系统调用 三、调用系统命令向进程发信号 kill 四、硬件异常 五、软件条件 三、信号的保存 四、信号的处理 一、预备知识 1.信号!信号量。两者没有任何关系 2.什么是信号? 定义一&…...
微软Edge浏览器字体设置
前言 时间:2025年4月 自2025年4月起,微软Edge浏览器的默认字体被微软从微软雅黑替换成了Noto Sans,如下图。Noto Sans字体与微软雅黑风格差不多,但在4K以下分辨率的显示器上较微软雅黑更模糊,因此低分辨率的显示器建议…...
Java中 关于编译(Compilation)、类加载(Class Loading) 和 运行(Execution)的详细区别解析
以下是Java中 编译(Compilation)、类加载(Class Loading) 和 运行(Execution) 的详细区别解析: 1. 编译(Compilation) 定义 将Java源代码(.java文件&#x…...
[python] set
1.添加元素 在 Python 中,向 set 添加一个元素可以使用 add() 方法。如果添加的元素已经存在于 set 中,add() 不会重复添加(因为 set 具有自动去重的特性)。 方法 1:add(element)(添加单个元素࿰…...
转化率提升47%?亚马逊用户行为预测模型深度解读
在亚马逊运营的战场上,谁能更精准地读懂用户行为,谁就更可能赢得转化率的胜利。近年来,越来越多卖家借助“用户行为预测模型”来优化Listing布局、广告投放策略、甚至库存管理,而这些数据驱动的决策也确确实实地带来了质的提升。 …...
C++计算 n! 中末尾零的数量
* 详细说明* 给定一个整数作为输入。目标是找出该数的阶乘结果中末尾零的数量。 一个数 N 的阶乘是范围 [1, N] 内所有数的乘积。* * 我们知道,只有当一个数是 10 的倍数或者有因数对 (2, 5) 时,才会产生末尾零。 在任何大于 5 的数的阶乘中,…...
大模型中超参数TopK是什么
大模型中的超参数Top-K是文本生成过程中的关键控制参数,主要用于平衡生成结果的确定性与多样性。以下从定义、工作原理、应用场景及与其他参数的协同关系进行详细阐述: 一、Top-K的定义与核心机制 基本定义 Top-K(Top-K Sampling)是一种基于概率采样的文本生成策略。其核心…...
NetApp ONTAP 9 故障磁盘更换操作指南
以前写过一篇7-mode的磁盘更换文档,好几个朋友反馈说命令都没有,都不对。主要原因是客户现在的环境都是ontap 9的cluster-mode环境了,所以很多命令都不一样了。为此,这里专门就ontap 9的cluster-mode写一篇磁盘更换操作指南&#…...
leetcode day 35 01背包问题 416+1049
0-1背包问题 (1)第一种情况:二维dp[i][j]数组 dp[i][j]表示[0,i]的物品放入容量为j背包的最大价值 不放物品i,dp[i][j]dp[i-1][j] 放物品i,dp[i][j]dp[i-1][j-w[i]]v[i] 递推公式为: dp[i][j]dp[i-1][j];//不放 if(w[i]<j)dp…...
MySQL的基本操作
显示所有数据库: SHOW DATABASES; 系统默认数据库: 数据库名用途information_schema存储 MySQL 服务器元数据(如数据库、表、列信息),只读mysql存储用户权限、密码、日志等核心数据(不要随意修改ÿ…...
CSS伪类、clip-path实现三角形、箭头绘制
<template><div :class"$options.name"><div class"triangle-container1"><!-- 伪类三角形:向右 --><div class"triangle-RM"></div><!-- 伪类三角形:向下 --><div class&q…...
基于大模型的腹股沟疝全流程预测与诊疗方案研究报告
目录 一、引言 1.1 研究背景与目的 1.2 研究方法与创新点 二、大模型在腹股沟疝术前评估中的应用 2.1 腹股沟疝概述与诊断方法 2.2 术前评估指标与数据收集 2.3 大模型预测原理与实现 2.4 预测结果与传统评估对比 三、基于大模型预测的手术方案制定 3.1 手术方式选择…...
零基础上手Python数据分析 (20):Seaborn 统计数据可视化 - 轻松绘制精美统计图表!
写在前面 —— 告别 Matplotlib 繁琐定制,拥抱 Seaborn 便捷之美,让统计可视化更高效 在前面两篇博客中,我们学习了 Python 数据可视化的基石 Matplotlib,掌握了绘制基础图表和进行高级定制的技巧。 Matplotlib 功能强大且灵活,能够满足几乎所有的二维绘图需求。 然而,…...
elasticsearch7.15节点磁盘空间满了迁移数据到新磁盘
一.数据安全迁移 在 Elasticsearch 中设置某个节点临时不可用(例如进行维护或升级),可以通过以下步骤安全地操作,避免数据丢失或集群状态异常 1: 排除节点分片分配,触发分片迁移到其他节点 PUT /_cluster/settings {&…...
MCP案例—客户端和服务端
MCP简介 Model Context Protocol (模型上下文协议),简称MCP,MCP是一种协议,用于LLM与外部拓展资源交互的协议。 想了解具体细节可参考作者本篇文章MCP理论指南 准备 本篇文章将带你通过python创建MCP客户端及服务端,并连接到本…...
排序模型(Learning to Rank)
排序模型(Learning to Rank) 要解决的问题 排序模型旨在解决信息检索中的排序优化问题。例如: 搜索引擎中对候选网页的排序推荐系统中物品的展示顺序广告系统中广告位的分配 核心挑战:根据上下文特征,将最相关/最有…...
L1-1、Prompt 是什么?为什么它能“控制 AI”?
*Prompt 入门 L1-1 想象一下,你只需输入一句话,AI 就能自动为你写一篇文案、生成一份报告、甚至规划你的创业计划。这种“对话即编程”的背后魔法,就是 Prompt 的力量。 🔍 一、Prompt 的定义与由来 Prompt(提示词&am…...
RolmOCR重磅开源:基于Qwen2.5-VL,速度提升40%,手写/倾斜文档识别准确率超92%
向大家介绍一款全新的开源OCR模型——RolmOCR!这款由Reducto AI团队基于阿里巴巴强大的Qwen2.5-VL-7B-Instruct视觉语言模型微调而来的利器,不仅在速度和效率上实现了显著提升(据称处理速度相比其前身olmOCR提升了约40%)ÿ…...
系统架构设计(二):基于架构的软件设计方法ABSD
“基于架构的软件设计方法”(Architecture-Based Software Design, ABSD)是一种通过从软件架构层面出发指导详细设计的系统化方法。它旨在桥接架构设计与详细设计之间的鸿沟,确保系统的高层结构能够有效指导后续开发。 ABSD 的核心思想 ABS…...