vector(c++)
前言
正式进入学习STL的第一步就是vector容器, vector是一种用于存储可变大小数组的序列容器,就像数组一样,vector也采用的连续存储空间来存储元素。本质上讲,vector使用动态分配数组来存储它的元素。底层是一个顺序表。本文介绍的是gcc使用的STL源码的vector容器,这也是业界比较认可的一种STL版本。后续的vector模拟实现一切都是向这个版本靠齐。
正文
vector使用
class Print
{
public:template<class T>static void printVector(vector<T> v){for (auto e : v){cout << e << " ";}}
};
这里我先把打印封装成一个类,方便后序测试的打印
vector的定义
vector::vector - C++ Reference | 接口说明 |
vector()(重点) | 无参构造 |
vector(size_type n, const value_type& val = value_type()) | 构造并初始化n个val |
vector (const vector& x); (重点) | 拷贝构造 |
vector (InputIterator first, InputIterator last); | 使用迭代器进行初始化构造 |
//vector的定义
void test01()
{//重点//初始化列表初始化(c++11特性) c++98不支持vector<int> v1 = { 1,2,3,4 };vector<int> v2(v1);Print::printVector(v1);cout << endl;Print::printVector(v2);cout << endl;vector<int> v3(10,-1);vector<int> v4(v1.begin(),v1.end());Print::printVector(v3);cout << endl;Print::printVector(v4);
}
这里着重掌握无参构造和拷贝构造,其他的了解即可
vector iterator 的使用
iterator的使用 | 接口说明 |
begin + end(重点) | 获取第一个数据位置的iterator/const_iterator, 获取最后一个数据的下一个位置 的iterator/const_iterator |
rbegin + rend | 获取最后一个数据位置的reverse_iterator,获取第一个数据前一个位置的 reverse_iterator |
//vector iterator 的使用
//正向迭代器和反向迭代器
void test02()
{vector<int> v1 = { 1,2,3,4 };vector<int> v2(v1);vector<int>::iterator it1 = v1.begin();while (it1 != v1.end()){cout << *it1 << " ";it1++;}cout << endl;auto it2 = v2.rbegin();while (it2 != v2.rend()){cout << *it2 << " ";it2++;}}
这里的迭代器没啥好说的,会使用就行,不过要注意迭代器失效,下面会着重讲。
vector 容量
容量空间 | 接口说明 |
size | 获取数据个数 |
capacity | 获取容量大小 |
empty | 判断是否为空 |
resize(重点) | 改变vector的size |
reserve (重点) | 改变vector的capacity |
//vector 容量
void test03()
{vector<int> v1 = { 1,2,3,4 };vector<int> v2(v1);//重点Print::printVector(v2);cout << endl;//大于size()v2.resize(10, -1);Print::printVector(v2);cout << endl;//小于size()v2.resize(3, -1);Print::printVector(v2);cout << endl;//size capacity emptysize_t size = v1.size();size_t capacity = v1.capacity();cout << "v1: " << size << " " << capacity << " " << (v1.empty() ? "true" : "false") << endl;}
和string的容量大差不差,会使用即可
vector 增删查改
vector 增删查改 | 接口说明 |
push_back(重点) | 尾插 |
pop_back (重点) | 尾删 |
find | 查找。(注意这个是算法模块实现,不是vector的成员接口) |
insert | 在position之前插入val |
erase | 删除position位置的数据 |
swap | 交换两个vector的数据空间 |
operator[] (重点) | 像数组一样访问 |
//vector 增删查改
void test04()
{vector<int> v1;//重点v1.push_back(1);v1.push_back(2);v1.push_back(3);v1.push_back(4);vector<int> v2(v1);v1.pop_back();cout << "v1:test: ";for (size_t i = 0; i < v1.size(); i++){cout << v1[i] << " ";}cout << endl;cout << "v2:test: ";for (size_t i = 0; i < v2.size(); i++){cout << v2[i] << " ";}cout << endl;//find insert erase swap//...就不测试了 大家自己测试下吧 都是很简单的
}
这里的增删查改和string的差不多,不过要注意vector并没有find接口,这个接口是算法的接口,就是再一段区间找值并返回迭代器而已,很简单。
vector 迭代器失效问题。(重点)
//vector 迭代器失效问题。(重点)
void test05()
{vector<int> v1 = { 1,2,3,4,5,6 };vector<int> v2(v1);auto it1 = v1.begin();while (it1 != v1.end()){if (*it1 % 2 == 0){v1.erase(it1);}else{it1++;}}Print::printVector(v1);auto it2 = v2.begin();while (it2 != v2.end()){if (*it2 % 2 == 0){it2 = v2.erase(it2);}else{it2++;}}Print::printVector(v2);
}
这里才是重点,要了解迭代器失效问题,就要先了解迭代器的原理底层,vector的迭代器底层本质还是指针实现的。所以指针就会涉及拷贝时的一个深浅拷贝,指针指向的地址的问题。由于是深拷贝,所以如果涉及到扩容,我们就会新开辟一块新空间,把原来的数据拷贝到这里。但是,迭代器还是指向原来空间的位置,原来的空间已经被释放掉,所以这里迭代器失效本质上就是一个野指针。那怎么解决这个问题呢?总不能不深拷贝吧?改变下参数吗?参数改变也没啥用呀。我erase是删除迭代器位置的数据,对你还要不要使用这个迭代器我没有义务保证你的安全呀?所以,我们对返回值做文章,返回要删除数据的下一个迭代器。这也是为啥insert会有一个返回值,返回插入位置的迭代器。
这里还涉及一个平台检查问题,下面这段代码在gcc下是可以编译通过的,但是在vs下直接报错
vector<int> v1 = { 1,2,3,4,5,6 };auto it1 = v1.begin();while (it1 != v1.end()){if (*it1 % 2 == 0){v1.erase(it1);}else{it1++;}}Print::printVector(v1);
因此,这里有一个结论,insert和erase之后我们一致认为你的迭代器是失效,使用它结果是未定义的。
vector的模拟实现
这里才是学习vector的重头戏,只有自己模拟实现一个vector,你才能正真理解这个容器的设计。
成员变量
private:T* _start = nullptr;T* _finish =nullptr;T* _endofstorage = nullptr;
为啥这里不是,size,capacity,_arr呢?咋是什么_finish?这是啥?其实这和STL的设计理念有关,这里从vector开始就几乎基本全面介入迭代器了。vector的迭代器底层就是T*。所以,他的变量要设计成这样也是为了向迭代器靠拢,_start就是数组的起始位置,_finish是 最后一个数据的下一个位置,_endifstorage就是容器的底部的下一个位置。这里我给了初始值(c++11打入的补丁),所以后面构造函数我没有在初始化值了。
这里先实现下swap函数,方便后续函数的编写。
void swap(vector<T>& v){std::swap(_start, v._start);std::swap(_finish, v._finish);std::swap(_endofstorage, v._endofstorage);}
默认成员函数
这里我使用的是直接new delete管理动态内存分配,但是原版STL使用的是空间配置器,其实底层还是包装new delete而已,但不过人家的这个空间配置器效率更高。对于我们初学者,先使用new delete就可以了,如果现在就要你学习空间配置器,让你掌握并使用。那可谓真的是从入门到放弃。一般来说空间配置器是c++很后面才会讲的。
构造 析构
vector()
{}
vector(size_t n,const T& val = T())
{resize(n, val);
}
vector(int n, const T& val = T())
{resize(n, val);
}
//再套一个类模板
//相比上一个构造函数 匹配程度更高 和类型有关
template<class InputIterator>
vector(InputIterator first, InputIterator last)
{while (first != last){push_back(*first);++first;}}
~vector(){if (_start){delete[] _start;_start = _finish = _endofstorage = nullptr;}}
这里构造析构没啥坑,就是正常实现就行。
拷贝构造
vector(const vector<T>& v){_start = new T[v.capacity()];//memcpy(_start, v._start, sizeof(T) * v.size());//解决对象的深拷贝for (size_t i = 0; i < size(); i++){_start[i] = v._start[i];}_finish = _start + v.size();_endofstorage = _start + v.capacity();}
这里是一个难点,主要是深拷贝的问题,对于内置类型的靠别没有问题。但是如果是自定义类型,使用memcpy就是一个浅拷贝。那如何解决呢?使用for循环,使用它们内部的赋值重载一个个赋值。
赋值重载
vector<T>& operator=(vector<T> v){swap(v);return *this;}
迭代器
这里我并没有实现反向迭代器
typedef T* iterator;
typedef const T* const_iterator;
iterator begin()
{return _start;
}
iterator end()
{return _finish;
}
const_iterator begin() const
{return _start;
}
const_iterator end() const
{return _finish;
}
容量操作
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 < size(); i++){tmp[i] = _start[i];}delete[] _start;}_start = tmp;_finish = _start + sz;_endofstorage = _start + n;}}//匿名对象当省略值 如果是内置类型 c++会特殊处理 升级成对象 调用无参构造void resize(size_t n, const T& val = T()){if (n < capacity()){_finish = _start + n;}else{reserve(n);while (_finish != _start + n){*_finish = val;_finish++;}}}size_t size() const{return _finish - _start;}size_t capacity() const{return _endofstorage - _start;}bool empty(){return size() == 0;}
这里的扩容,和上面拷贝构造函数内部迭代器失效是一个原理,所以我们也要换一下拷贝,不能使用memcpy。
增删查改和访问引用操作
访问引用
T& operator[](size_t pos){assert(pos < size());return _start[pos];}const T& operator[](size_t pos) const{assert(pos < size());return _start[pos];}
增删查改
iterator erase(iterator pos){assert(pos >= _start && pos < _finish);iterator end = pos;while (end < _finish){*end = *(end + 1);end++;}_finish--;return pos;}iterator erase(iterator first, iterator last){assert(first >= _start && first <= _finish);assert(last >= _start && last <= _finish);assert(first <= _finish);iterator it1 = first, it2 = last;size_t len = last - first;//1 2 3 4 5while (it1 <= last){*it1 = *(it2);it1++;it2++;}_finish -= len;return last;}void push_back(const T& x){if (_finish == _endofstorage){size_t newcapacity = capacity() == 0 ? 4 : 2 * capacity();reserve(newcapacity);}*_finish = x;_finish++;}void pop_back(){erase(--end());}iterator insert(iterator pos, const T& x){assert(pos >= _start && pos <= _finish); //等于就是尾插和头插if (_finish == _endofstorage){size_t len = pos - _start;size_t newcapacity = capacity() == 0 ? 4 : 2 * capacity();reserve(newcapacity);//解决内部迭代器失效pos = _start + len;}iterator end = _finish - 1;while (end >= pos){*(end + 1) = *end;end--;}*pos = x;_finish++;return pos;}
vector实现二维数组
实际上就是一个函数套一个函数而已,那这样岂不是效率很低,放心它会直接升级内联的。和c++讲效率低,你简直是在侮辱它?
void test06()
{vector<vector<int>> arr = { {1,},{1,2},{1,2,3} };//vector<vector<int>>for (auto e : arr){//e : vector<int>for (auto i : e){//i intcout << i << " ";}cout << endl;}
}
源码
#pragma once
#include <stdio.h>
#include <assert.h>
//vector insert和erase之后我们认为迭代器是失效的
//访问结果是未定义的
namespace che
{template<class T>class vector{public:typedef T* iterator;typedef const T* const_iterator;iterator begin(){return _start;}iterator end(){return _finish;}const_iterator begin() const{return _start;}const_iterator end() const{return _finish;}vector(){}vector(size_t n,const T& val = T()){resize(n, val);}vector(int n, const T& val = T()){resize(n, val);}//再套一个类模板//相比上一个构造函数 匹配程度更高 和类型有关template<class InputIterator>vector(InputIterator first, InputIterator last){while (first != last){push_back(*first);++first;}}vector(const vector<T>& v){_start = new T[v.capacity()];//memcpy(_start, v._start, sizeof(T) * v.size());//解决对象的深拷贝for (size_t i = 0; i < size(); i++){_start[i] = v._start[i];}_finish = _start + v.size();_endofstorage = _start + v.capacity();}//其他写法~vector(){if (_start){delete[] _start;_start = _finish = _endofstorage = nullptr;}}void swap(vector<T>& v){std::swap(_start, v._start);std::swap(_finish, v._finish);std::swap(_endofstorage, v._endofstorage);}vector<T>& operator=(vector<T> v){swap(v);return *this;}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 < size(); i++){tmp[i] = _start[i];}delete[] _start;}_start = tmp;_finish = _start + sz;_endofstorage = _start + n;}}iterator erase(iterator pos){assert(pos >= _start && pos < _finish);iterator end = pos;while (end < _finish){*end = *(end + 1);end++;}_finish--;return pos;}iterator erase(iterator first,iterator last){assert(first >= _start && first <= _finish);assert(last >= _start && last <= _finish);assert(first <= _finish);iterator it1 = first, it2 = last;size_t len = last - first;//1 2 3 4 5while (it1 <= last){*it1 = *(it2);it1++;it2++;}_finish-=len;return last;}void push_back(const T& x){if (_finish == _endofstorage){size_t newcapacity = capacity() == 0 ? 4 : 2 * capacity();reserve(newcapacity);}*_finish = x;_finish++;}//匿名对象当省略值 如果是内置类型 c++会特殊处理 升级成对象 调用无参构造void resize(size_t n, const T& val = T()){if (n < capacity()){_finish = _start + n;}else{reserve(n);while (_finish != _start + n){*_finish = val;_finish++;}}}void pop_back(){erase(--end());}iterator insert(iterator pos, const T& x){assert(pos >= _start && pos <= _finish); //等于就是尾插和头插if (_finish == _endofstorage){size_t len = pos - _start;size_t newcapacity = capacity() == 0 ? 4 : 2 * capacity();reserve(newcapacity);//解决内部迭代器失效pos = _start + len;}iterator end = _finish - 1;while (end >= pos){*(end + 1) = *end;end--;}*pos = x;_finish++;return pos;}size_t size() const{return _finish - _start;}size_t capacity() const{return _endofstorage - _start;}T& operator[](size_t pos){assert(pos < size());return _start[pos];}const T& operator[](size_t pos) const{assert(pos < size());return _start[pos];}private:T* _start = nullptr;T* _finish =nullptr;T* _endofstorage = nullptr;};
}
总结
相比string的学习,你会发现vector的学习是很轻松的,就是一些基本的顺序表的函数实现,比较难的就是他的迭代器失效问题。会涉及到深浅拷贝以及如何处理的问题,这和他的设计理念是息息相关的。
相关文章:
vector(c++)
前言 正式进入学习STL的第一步就是vector容器, vector是一种用于存储可变大小数组的序列容器,就像数组一样,vector也采用的连续存储空间来存储元素。本质上讲,vector使用动态分配数组来存储它的元素。底层是一个顺序表。本文介绍…...
CAPL Class: TcpSocket (此类用于实现 TCP 网络通信 )
目录 Class: TcpSocketacceptopenclosebindconnectgetLastSocketErrorgetLastSocketErrorAsStringlistenreceivesendsetSocketOptionshutdown函数调用的基本流程服务器端的基本流程客户端的基本流程Class: TcpSocket学习笔记。来自CANoe帮助文档。 Class: TcpSocket accept /…...
C语言:gcc 如何调用 Win32 打开文件对话框 ?
在 Windows 平台上使用 gcc 调用原生 Win32 API 实现文件打开对话框是可行的,但需要直接使用 Win32 的 GetOpenFileName 函数(位于 commdlg.h 头文件,依赖 comdlg32.lib 库)。以下是完整实现步骤和代码示例: 编写 file…...
OpenHarmony:开源操作系统重塑产业数字化底座
OpenHarmony:开源操作系统重塑产业数字化底座 引言:当操作系统成为数字公共品 在万物智联时代,操作系统不再是科技巨头的专属领地。华为捐赠的OpenHarmony项目,正以开源协作模式重构操作系统产业格局。这个脱胎于商业版本的开源…...
线程同步学习
概念 有A、B、C三个线程,A线程负责输入数据,B线程负责处理数据、C线程负责输出数据,这三个线程之间就存在着同步关系,即A必须先执行,B次之,C最后执行,否则不能得到正确的结果。 那么所谓线程同…...
十二、Hive 函数
作者:IvanCodes 日期:2025年5月17日 专栏:Hive教程 在数据处理的广阔天地中,我们常常需要对数据进行转换、计算、清洗或提取特定信息。Hive 提供了强大的内置运算符和丰富的内置函数库,它们就像魔法师手中的魔法棒&…...
DeepSeek 赋能社会科学:解锁研究新范式
目录 一、DeepSeek:大语言模型中的新力量1.1 DeepSeek 技术亮点1.2 与其他模型对比 二、DeepSeek 在社会科学研究中的应用领域2.1 经济学研究2.2 社会学研究2.3 历史学研究2.4 法学研究 三、DeepSeek 应用案例深度剖析3.1 案例一:社会学研究中社会舆情分…...
java函数内的变量问题
public class VendingMachine {//设计一个类叫做VendingMachine,用这个类制造一个对象vmint price 80;int balance;//三个属性int total;void showprompt(){System.out.println("Welcome");}void insertmoney(int amount){balance balance amount;}void showBalan…...
docker部署第一个Go项目
1.前期准备 目录结构 main.go package mainimport ("fmt""github.com/gin-gonic/gin""net/http" )func main() {fmt.Println("\n .::::.\n .::::::::.\n :::::::::::\n …...
【读代码】端到端多模态语言模型Ultravox深度解析
一、项目基本介绍 Ultravox是由Fixie AI团队开发的开源多模态大语言模型,专注于实现音频-文本的端到端实时交互。项目基于Llama 3、Mistral等开源模型,通过创新的跨模态投影架构,绕过了传统语音识别(ASR)的中间步骤,可直接将音频特征映射到语言模型的高维空间。 核心优…...
管理前端项目依赖版本冲突导致启动失败的问题的解决办法
管理前端项目依赖版本冲突导致启动失败的问题,可按照以下步骤系统解决: 1. 定位冲突来源 查看错误日志:启动失败时的控制台报错通常会指出具体模块或版本问题,例如 Module not found 或 TypeError。检查依赖树:npm l…...
北京市工程技术人才职称评价基本标准条件解读
北京市工程技术人才职称评价基本标准条件 北京市工程技术人才之技术员 北京市工程技术人才之助理工程师 北京市工程技术人才之工程师 北京市工程技术人才之高级工程师 北京市工程技术人才之高级工程师(破格) 北京市工程技术人才之正高级工程师 北京市工程…...
MUSE Pi Pro 开发板 Imagination GPU 利用 OpenCL 测试
视频讲解: MUSE Pi Pro 开发板 Imagination GPU 利用 OpenCL 测试 继续玩MUSE Pi Pro,今天看下比较关注的gpu这块,从opencl看起,安装clinfo指令 sudo apt install clinfo 可以看到这颗GPU是Imagination的 一般嵌入式中gpu都和hos…...
Mysql数据库之集群进阶
一、日志管理 5.7版本自定义路径时的文件需要自己提前创建好文件,不会自动创建,否则启动mysql会报错 错误日志 rpm包(yum) /var/log/mysql.log 默认错误日志 ###查询日志路径 [rootdb01 ~]# mysqladmin -uroot -pEgon123 variables | grep -w log_e…...
JavaScript防抖与节流全解析
文章目录 前言:为什么需要防抖和节流基本概念与区别防抖(Debounce)节流(Throttle)关键区别防抖(Debounce)详解1. 基本防抖函数实现2. 防抖函数的使用3. 防抖函数的工作流程4. 防抖函数进阶 - 立即执行选项节流(Throttle)详解1. 基本节流函数实现时间戳法(第一次会立即执行)定…...
大模型学习:Deepseek+dify零成本部署本地运行实用教程(超级详细!建议收藏)
文章目录 大模型学习:Deepseekdify零成本部署本地运行实用教程(超级详细!建议收藏)一、Dify是什么二、Dify的安装部署1. 官网体验2. 本地部署2.1 linux环境下的Docker安装2.2 Windows环境下安装部署DockerDeskTop2.3启用虚拟机平台…...
在RK3588上使用NCNN和Vulkan加速ResNet50推理全流程
在RK3588上使用NCNN和Vulkan加速ResNet50推理全流程 前言:为什么需要关注移动端AI推理一、环境准备与框架编译1.1 获取NCNN源码1.2 安装必要依赖1.3 编译NCNN二、模型导出与转换2.1 生成ONNX模型2.2 转换NCNN格式三、模型量化加速3.1 生成校准数据3.2 执行量化操作四、性能测试…...
Web安全基础:深度解析与实战指南
一、Web安全体系架构的全面剖析 1.1 分层防御模型(Defense in Depth) 1.1.1 网络层防护 防火墙技术: 状态检测防火墙(SPI):基于连接状态跟踪,阻断非法会话(如SYN Flood攻击)下一代防火墙(NGFW):集成IPS、AV、URL过滤(如Palo Alto PA-5400系列)配置示例…...
Uniapp开发鸿蒙应用时如何运行和调试项目
经过前几天的分享,大家应该应该对uniapp开发鸿蒙应用的开发语法有了一定的了解,可以进行一些简单的应用开发,今天分享一下在使用uniapp开发鸿蒙应用时怎么运行到鸿蒙设备,并且在开发中怎么调试程序。 运行 Uniapp项目支持运行到…...
Python海龟绘图(Turtle Graphics)核心函数和关键要点
以下是Python海龟绘图(Turtle Graphics)的核心函数和关键要点整理: 一、画布设置 函数/方法说明参数说明备注turtle.setup(width, height, x, y)设置画布尺寸和位置width宽度,height高度,x/y窗口左上角坐标默认尺寸80…...
如何在Cursor中高效使用MCP协议
1、Cursor介绍 Cursor是一个功能强大的开发工具,内置了聊天助手、代码自动补全和调试工具,能够与多种外部工具和服务(如数据库、文件系统、浏览器等)进行深度集成。借助MCP(Multiverse Communication Protocol&#x…...
典籍知识问答模块AI问答bug修改
一、修改流式数据处理问题 1.问题描述:由于传来的数据形式如下: event:START data:350 data:< data:t data:h data:i data:n data:k data:> data: data: data: data: data:嗯 data:, 导致需要修改获取正常的当前信息id并更…...
Redis 发布订阅模式深度解析:原理、应用与实践
在现代分布式系统架构中,实时消息传递机制扮演着至关重要的角色。Redis 作为一款高性能的内存数据库,其内置的发布订阅(Pub/Sub)功能提供了一种轻量级、高效的消息通信方案。本文将全面剖析 Redis 发布订阅模式,从其基本概念、工作原理到实际…...
通义千问-langchain使用构建(三)
目录 序言docker 部署xinference1WSL环境docker安装2拉取镜像运行容器3使用的界面 本地跑chatchat1rag踩坑2使用的界面2.1配置个前置条件然后对话2.2rag对话 结论 序言 在前两天的基础上,将xinference调整为wsl环境,docker部署。 然后langchain chatcha…...
c++ 仿函数
示例代码: void testFunctor() {using Sum struct MyStruct {int operator() (int a, int b) const { // 重载()运算符return a b;}};Sum sum;std::cout << sum(9528, -1) << std::endl; } 打印: 仿函数意思是&am…...
hyper-v 虚拟机怎么克隆一台一样的虚拟机?
环境: hyper-v Win10专业版 问题描述: hyper-v 虚拟机怎么克隆一台一样的虚拟机? 解决方案: 以下是在 Hyper-V 中克隆虚拟机的几种方法: 方法一:使用导出和导入功能 导出虚拟机: 打开 H…...
操作系统:os概述
操作系统:OS概述 程序、进程与线程无极二级目录三级目录 程序、进程与线程 指令执行需要那些条件?CPU内存 需要数据和 无极 二级目录 三级目录...
【技巧】GoogleChrome浏览器开发者模式查看dify接口
回到目录 GoogleChrome浏览器开发者模式查看dify接口 1.搭建本地dify开发环境 参考 《 win10的wsl环境下调试dify的api后端服务(20250511发布)》 2.打开dify首页,进入开发者模式,Network页 勾选 Preserve log [图1] 3.填好用户名和密码,…...
Ocean: Object-aware Anchor-free Tracking
领域:Object tracking It aims to infer the location of an arbitrary target in a video sequence, given only its location in the first frame 问题/现象: Anchor-based Siamese trackers have achieved remarkable advancements in accuracy, yet…...
java中的循环结构
文章目录 流程控制顺序结构if单选择结构if双选择结构if多选择结构嵌套的if结构switch多选择结构 循环结构while循环do...while循环 for循环增强for循环 break continue练习案例 流程控制 顺序结构 java的基本结果就是顺序结构,除非特别指明,否则就按照…...
数学复习笔记 16
前言 例题真是经典。 background music 《青春不一样》 2.28 算一个行列式,算出来行列式不等于零,这表示矩阵式可逆的。但是这个算的秩是复合的,感觉没啥好办法了,我直接硬算了,之后再看解析积累好的方法。算矩阵…...
PySide6 GUI 学习笔记——常用类及控件使用方法(常用类颜色QColor)
文章目录 一、概述二、核心功能三、常用函数及方法四、代码示例五、注意事项 一、概述 QColor 是用于处理颜色的类,支持 RGB、HSV、HSL、CMYK 等多种颜色模型,提供颜色创建、转换、分量操作及格式转换功能。支持透明度设置,可通过颜色名称或…...
【Closure-Hayd】
RNA序列本身存在结构上的物理信息,因此可以利用文献提供的相关方法来对RNA序列的物理特征进行更加细致的提取。 几何向量编码(GVP模块)借鉴Rhodesign模型中的GVP(Geometric Vector Perceptron)模块,将每个…...
MySQL高可用架构
一、读写分离在高可用架构中的核心作用 1.读写分离与高可用的协同价值 在MySQL高可用架构中,读写分离不仅是性能优化的手段,更是提升系统容错能力的关键策略。通过将写操作(INSERT、UPDATE、DELETE) 集中到主节点,读…...
粒子群算法(PSO算法)
粒子群算法概述 1.粒子群优化算法(Particle Swarm Optimization,简称PSO)。粒子群优化算法是在1995年由Kennedy博士和Eberhart博士一起提出的,它源于对鸟群捕食行为的研究。 2.基本核心是利用群体中的个体对信息的共享从而使得整…...
信道编码技术介绍
信息与通信系统中的编码有4 种形式:信源编码、信道编码、密码编码和多址编码。 其中信道编码的作用是对信源经过压缩后的数据加一定数量受到控制的冗余,使得数据在传输中或接收中发生的差错可以被纠正或被发现,从而可以正确恢复出原始数据信息…...
JavaScript【4】数组和其他内置对象(API)
1.数组: 1.概述: js中数组可理解为一个存储数据的容器,但与java中的数组不太一样;js中的数组更像java中的集合,因为此集合在创建的时候,不需要定义数组长度,它可以实现动态扩容;js中的数组存储元素时,可以存储任意类型的元素,而java中的数组一旦创建后,就只能存储定义类型的元…...
【背包dp-----分组背包】------(标准的分组背包【可以不装满的 最大价值】)
通天之分组背包 题目链接 题目描述 自 01 01 01 背包问世之后,小 A 对此深感兴趣。一天,小 A 去远游,却发现他的背包不同于 01 01 01 背包,他的物品大致可分为 k k k 组,每组中的物品相互冲突,现在&a…...
docker-compose——安装mongo
编写docker-compose.yml version : 3.8services:zaomeng-mongodb:container_name: zaomeng-mongodbimage: mongo:latestrestart: alwaysports:- 27017:27017environment:- MONGO_INITDB_ROOT_USERNAMEroot- MONGO_INITDB_ROOT_PASSWORDpssw0rdvolumes:- ./mongodb/data:/data/…...
day 28
类 一个常见的类的定义包括了: 1. 关键字class 2. 类名 3. 语法固定符号冒号(:) 4. 一个初始化函数__init__(self) Pass占位符和缩进 Python 通过缩进来定义代码块的结构。当解释器遇到像 def, class, if, for 这样的语句,并且后面跟着冒号 : 时&…...
JavaScript入门【1】概述
1.JavaScript是什么? <font style"color:rgb(38,38,38);">Javascript (简称“JS”)是⼀种直译式脚本语⾔,⼀段脚本其实就是⼀系列指令,计算机通过这些指令来达成⽬标。它⼜是⼀种动态类型的编程语⾔。JS⽤来在⽹…...
MySQL 中 JOIN 和子查询的区别与使用场景
目录 一、JOIN:表连接1.1 INNER JOIN:内连接1.2 LEFT JOIN:左连接1.3 RIGHT JOIN:右连接1.4 FULL JOIN:全连接二、子查询:嵌套查询2.1 WHERE 子句中的子查询2.2 FROM 子句中的子查询2.3 SELECT 子句中的子查询三、JOIN 和子查询的区别3.1 功能差异3.2 性能差异3.3 使用场…...
DeepSeek 大模型部署全指南:常见问题、优化策略与实战解决方案
DeepSeek 作为当前最热门的开源大模型之一,其强大的语义理解和生成能力吸引了大量开发者和企业关注。然而在实际部署过程中,无论是本地运行还是云端服务,用户往往会遇到各种技术挑战。本文将全面剖析 DeepSeek 部署中的常见问题,提…...
Python 3.11详细安装步骤(包含安装包)Python 3.11详细图文安装教程
文章目录 前言Python 3.11介绍Python 3.11安装包下载Python 3.11安装步骤 前言 作为当前最热门的编程语言之一,Python 3.11 不仅拥有简洁优雅的语法,还在性能上实现了飞跃,代码运行速度提升显著。无论是初入编程的小白,还是经验丰…...
虚拟主播肖像权保护,数字时代的法律博弈
首席数据官高鹏律师团队 在虚拟主播行业蓬勃发展的表象之下,潜藏着一场关乎法律边界的隐形战争。当一位虚拟偶像的3D模型被非法拆解、面部数据被批量复制,运营方惊讶地发现——传统的肖像权保护体系,竟难以完全覆盖这具由代码与数据构成的“…...
硬件工程师笔记——二极管Multisim电路仿真实验汇总
目录 1 二极管基础知识 1.1 工作原理 1.2 二极管的结构 1.3 PN结的形成 1.4 二极管的工作原理详解 正向偏置 反向偏置 multisim使用说明链接 2 二极管特性实验 2.1 二极管加正向电压 2.2 二极管加反向电压 2.3 二极管两端的电阻 2.4 交流电下二级管工作 2.5 二极…...
学习笔记(C++篇)—— Day 6
1.内部类 如果一个类定义在另一个类的内部,就叫做内部类。 例如下面一个代码示例: class A { private:static int _k;int _h 1; public:class B // B默认就是A的友元{public:void foo(const A& a){cout << _k << endl; //OKcout <&…...
常见的实时通信技术(轮询、sse、websocket、webhooks)
1. HTTP轮询:最老实的办法 刚开始做实时功能时,我第一个想到的就是轮询。特别简单直白,就像你每隔5分钟就刷新一次朋友圈看看有没有新消息一样。 短轮询:勤快但费劲 短轮询就是客户端隔三差五地问服务器:"有新…...
2025年第三届盘古石杯初赛(智能冰箱,监控部分)
前言 所以去哪里可以取到自己家里的智能家居数据呢???? IOT物联网取证 1、分析冰箱,请问智能冰箱的品牌? [答案格式:xiaomi] Panasonic2、请问智能冰箱的型号? [答案格式&#x…...
[强化学习的数学原理—赵世钰老师]学习笔记02-贝尔曼方程
本人为强化学习小白,为了在后续科研的过程中能够较好的结合强化学习来做相关研究,特意买了西湖大学赵世钰老师撰写的《强化学习数学原理》中文版这本书,并结合赵老师的讲解视频来学习和更深刻的理解强化学习相关概念,知识和算法技…...