【C++】深入哈希表核心:从改造到封装,解锁 unordered_set 与 unordered_map 的终极奥义!
文章目录
- 修改哈希表
- 模板参数
- 迭代器
- ``HashTable`` 的默认成员函数
- ``HashTable`` 迭代器相关函数
- ``HashTable`` 的 ``Insert`` 函数
- ``HashTable`` 的 ``Find``函数
- ``HashTable`` 的 ``Erase``函数
- 封装 unordered_set
- 封装 unordered_map
- 测试 unordered_set 和 unordered_map
修改哈希表
我们基于链地址法实现的哈希表来封装实现 unordered_set
和 unordered_map
,但是由于实现的哈希表是 Key-Value
结构的并且我们的实现的哈希表缺少了迭代器,所以我们需要对之前实现的哈希表进行改造。
模板参数
HashNode
节点里不再存储确定的 pair<K, V>
,而是类型 T
,代表代表存储的数据可能是 key
或者 key-Value
。
template<class T>
struct HashNode
{T _data;HashNode<T>* _next;HashNode(const T& data):_data(data), _next(nullptr){}
};
HashTable
template<class K, class T, class KeyOfT, class hash = HashFunc<K>>
class HashTable
K
:代表的是key
T
:代表是存的可能是key
或者key-value
KeyOfT
:仿函数,目的是拿到T
里面的key
迭代器
哈希表的迭代器其实就是对节点指针进行封装,而且是单向迭代器,只需实现 ++
即可。
//哈希表与迭代器相互依赖,需要前置声明
template<class K, class T, class KeyOfT, class hash>
class HashTable;template<class K, class T, class KeyOfT, class Hash, class Ref, class Ptr>
struct HTIterator
{typedef HashNode<T> Node;typedef HashTable<K, T, KeyOfT, Hash> HT;typedef HTIterator<K, T, KeyOfT, Hash, Ref, Ptr> Self;Node* _node;//需要用到哈希表里的数组大小,故需要指向哈希表的指针const HT* _pht;HTIterator(Node* node, const HT* pht):_node(node),_pht(pht){}Ref operator*(){return _node->_data;}Ptr operator->(){return &_node->_data;}bool operator!=(const Self& s){return _node != s._node;}Self& operator++(){//...}
};
由于哈希表的特殊性,其迭代器的 ++
较为复杂,也是实现哈希表迭代器的重点。
重载 ++
迭代器的++分为两种情况:
- 当前迭代器不是哈希桶的最后一个节点,直接走到下一个节点。
- 当前迭代器是哈希桶的最后一个节点,需要找下一个不为空的哈希桶的头节点。
Self& operator++()
{//当前哈希桶还有数据,直接到下一个节点if (_node->_next){_node = _node->_next;}//当前哈希桶走完了,寻找下一个不为空的哈希桶else if (_node->_next == nullptr){KeyOfT kot;Hash hashfunc;size_t hashi = hashfunc(kot(_node->_data)) % _pht->_tables.size();++hashi;while (hashi < _pht->_tables.size()){_node = _pht->_tables[hashi];//找到了下一个桶if (_node)break;else++hashi;}//处理迭代器在最后一个不为空的哈希桶的最后一个节点的情况if (hashi == _pht->_tables.size()){_node = nullptr;}}return *this;
}Self& operator++(int)
{Self tmp = *this;++(*this);return tmp;
}
HashTable
的默认成员函数
//构造函数
HashTable(): _tables(__stl_next_prime(0)), _n(0)
{}//拷贝构造函数
HashTable(const HashTable<K, T, KeyOfT, hash>& ht)
{_tables.resize(ht._tables.size());for (auto& data : ht){Insert(data);}
}//赋值重载
HashTable<K, T, KeyOfT, hash>& operator=(const HashTable<K, T, KeyOfT, hash>& ht)
{vector<Node*> newtables(ht._tables.size());for (size_t i = 0; i < ht._tables.size(); ++i){Node* cur = ht._tables[i];while (cur){Node* newnode = new Node(cur->_data);newnode->_next = newtables[i];newtables[i] = newnode;cur = cur->_next;}}_tables.swap(newtables);return *this;
}
//析构函数
~HashTable()
{for (size_t i = 0; i < _tables.size(); ++i){Node* cur = _tables[i];while (cur){Node* next = cur->_next;delete cur;cur = next;}_tables[i] = nullptr;}
}
HashTable
迭代器相关函数
typedef HTIterator<K, T, KeyOfT, hash, T&, T*> Iterator;
typedef HTIterator<K, T, KeyOfT, hash, const T&, const T*> Const_Iterator;Iterator begin()
{if (_n == 0)return end();for (size_t i = 0; i < _tables.size(); ++i){Node* cur = _tables[i];if (cur){return Iterator(cur, this);}}return end();
}Iterator end()
{return Iterator(nullptr, this);
}Const_Iterator begin() const
{if (_n == 0)return end();for (size_t i = 0; i < _tables.size(); ++i){Node* cur = _tables[i];if (cur){return Const_Iterator(cur, this);}}}Const_Iterator end() const
{return Const_Iterator(nullptr, this);
}
begin()
对应的迭代器应该是哈希表中第一个非空的哈希桶的头节点,需要特别处理。
end()
直接返回空指针对应的迭代器即可。
HashTable
的 Insert
函数
对于 Insert
函数,只需将其返回值改成迭代器与布尔值的 pair
,再将原本关于使用到 key
的地方套一层 KeyOfT
实例化出来的对象即可。
void CheckCapacity()
{if (_n == _tables.size()){//把哈od希桶里的链表每个节点拆下来插入newht效率太低了/*HashTable<K, V> newht;newht._tables.resize(__stl_next_prime(_tables.size() + 1));for (size_t i = 0; i < _tables.size(); ++i){Node* cur = _tables[i];while (cur){newht.Insert(cur->_kv);cur = cur->_next;}}_tables.swap(newht._tables);*/KeyOfT kot;hash hashfunc;vector<Node*> newtables(__stl_next_prime(_tables.size() + 1));for (size_t i = 0; i < _tables.size(); ++i){Node* cur = _tables[i];while (cur){Node* next = cur->_next;size_t hashi = hashfunc(kot(cur->_data)) % newtables.size();//头插cur->_next = newtables[hashi];newtables[hashi] = cur;cur = next;}_tables[i] = nullptr;}_tables.swap(newtables);}
}pair<Iterator, bool> Insert(const T& data)
{KeyOfT kot;Iterator it = Find(kot(data));//不等于end()说明哈希表里有重复元素if (it != end())return { it, false };//检查是否需要扩容CheckCapacity();hash hashfunc;size_t hashi = hashfunc(kot(data)) % _tables.size();Node* newnode = new Node(data);newnode->_next = _tables[hashi];_tables[hashi] = newnode;++_n;return { Iterator(newnode, this), false };
}
HashTable
的 Find
函数
将返回值改为迭代器,原本用到 key
的地方套一层 KeyOfT
实例化出来的对象即可。
Iterator Find(const K& key)
{KeyOfT kot;hash hashfunc;size_t hashi = hashfunc(key) % _tables.size();Node* cur = _tables[hashi];while (cur){if (kot(cur->_data) == key){return Iterator(cur, this);}cur = cur->_next;}//没找到就返回return end();
}
HashTable
的 Erase
函数
跟 Insert
函数的处理基本一样,不多叙述了。
bool Erase(const K& key)
{KeyOfT kot;hash hashfunc;size_t hashi = hashfunc(key) % _tables.size();Node* prev = nullptr;Node* cur = _tables[hashi];while (cur){if (kot(cur->_data) == key){//删除头节点的情况if (prev == nullptr){_tables[hashi] = cur->_next;}//非头节点的情况else{prev->_next = cur->_next;}delete cur;--_n;return true;}else {prev = cur;cur = cur->_next;}}return false;
}
封装 unordered_set
对 HashTable
的迭代器和函数进行封装即可,灰常简单。
template<class K, class hash = HashFunc<K>>
class unordered_set
{struct SetKeyOfT{const K& operator()(const K& key){return key;}};public:typedef typename hash_bucket::HashTable<K, const K, SetKeyOfT, hash>::Iterator iterator;typedef typename hash_bucket::HashTable<K, const K, SetKeyOfT, hash>::Const_Iterator const_iterator;iterator begin(){return _ht.begin();}iterator end(){return _ht.end();}const_iterator begin() const{return _ht.begin();}const_iterator end() const{return _ht.end();}pair<iterator, bool> Insert(const K& key){return _ht.Insert(key);}iterator Find(const K& key){return _ht.Find(key);}bool Erase(const K& key){return _ht.Erase(key);}private:hash_bucket::HashTable<K, const K, SetKeyOfT, hash> _ht;
};
封装 unordered_map
也是对 HashTable
的迭代器和函数进行封装,但有所不同的是,还需要多重载 []
,也比较简单。
template<class K, class V, class hash = HashFunc<K>>
class unordered_map
{struct MapKeyOfT{const K& operator()(const pair<K, V>& kv){return kv.first;}};public:typedef typename hash_bucket::HashTable<K, pair<const K, V>, MapKeyOfT, hash>::Iterator iterator;typedef typename hash_bucket::HashTable<K, pair<const K, V>, MapKeyOfT, hash>::Const_Iterator const_iterator;iterator begin(){return _ht.begin();}iterator end(){return _ht.end();}const_iterator begin() const{return _ht.begin();}const_iterator end() const{return _ht.end();}pair<iterator, bool> Insert(const pair<K, V>& kv){return _ht.Insert(kv);}V& operator[](const K& key){pair<iterator, bool> ret = Insert({ key, V() });return ret.first->second;}iterator Find(const K& key){return _ht.Find(key);}bool Erase(const K& key){return _ht.Erase(key);}private:hash_bucket::HashTable<K, pair<const K, V>, MapKeyOfT, hash> _ht;
};
测试 unordered_set 和 unordered_map
拜拜,下期再见😏
摸鱼ing😴✨🎞
相关文章:
【C++】深入哈希表核心:从改造到封装,解锁 unordered_set 与 unordered_map 的终极奥义!
文章目录 修改哈希表模板参数迭代器HashTable 的默认成员函数HashTable 迭代器相关函数HashTable 的 Insert 函数HashTable 的 Find函数HashTable 的 Erase函数 封装 unordered_set封装 unordered_map测试 unordered_set 和 unordered_map 修改哈希表 我们基于链地址法实现的哈…...
蓝桥杯模拟
【问题描述】 如果一个数 p 是个质数,同时又是整数 a 的约数,则 p 称为 a 的一个质因数。 请问 2024 有多少个质因数。 【答案提交】 这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只…...
16. 【.NET 8 实战--孢子记账--从单体到微服务】--汇率获取定时器
这篇文章我们将一起编写这个系列专栏中第一个和外部系统交互的功能:获取每日汇率。下面我们一起来编写代码吧。 一、需求 根据文章标题可知,在这片文章中我们只进行汇率的获取和写入数据库。 编号需求说明1获取每日汇率1. 从第三方汇率API中获取汇率信…...
移动充储机器人“小奥”的多场景应用(上)
一、高速公路服务区应用 在高速公路服务区,新能源汽车的充电需求得到“小奥”机器人的及时响应。该机器人配备有储能电池和自动驾驶技术,能够迅速定位至指定充电点,为待充电的新能源汽车提供服务。得益于“小奥”的机动性,其服务…...
【Android】Service使用方法:本地服务 / 可通信服务 / 前台服务 / 远程服务(AIDL)
1 本地Service 这是最普通、最常用的后台服务Service。 1.1 使用步骤 步骤1:新建子类继承Service类:需重写父类的onCreate()、onStartCommand()、onDestroy()和onBind()方法步骤2:构建用于启动Service的Intent对象步骤3:调用st…...
Qt文件目录操作
文件目录操作相关类 Qt 为文件和目录操作提供了一些类,利用这些类可以方便地实现一些操作。Qt 提供的与文件和目录操作相关的类包括以下几个: QCoreApplication:用于提取应用程序路径,程序名等文件信息;QFile&#x…...
刷题-1122
1. 蛇形矩阵是由1开始的自然数依次排列成的一个矩阵上三角形。 例如,当输入5时,应该输出的三角形为: 1 3 6 10 15 2 5 9 14 4 8 13 7 12 11 import sys def generate_snake_matrix(n):matrix [[0]*n for _ in range(n)]curent_num 1…...
【通俗理解】Jensen不等式与变分分布q(z)在积分计算中的应用
【通俗理解】Jensen不等式与变分分布q(z)在积分计算中的应用 关键词提炼 #Jensen不等式 #变分分布 #积分计算 #期望 #凸函数 #优化问题 #下界估计 #机器学习 第一节:Jensen不等式与变分分布的类比与核心概念【尽可能通俗】 Jensen不等式就像是一个“积分计算器”…...
微信小程序2-地图显示和地图标记
一、index修改页面,让页面能够显示地图和一个添加标记的按钮。 index.wxml <scroll-view class"scrollarea" scroll-y type"list"><view class"index_container"><map id"map" style"width: 100%; h…...
webpack配置和打包性能优化
文章目录 webpack基础配置loaderpluginloader 和 plugin 的区别devServer打包性能优化1、按需引入组件2、externals 属性3、给定文件匹配范围4、noParse 属性5、cacheDirectory 缓存属性6、happyPack 多个子进程并行 webpack基础配置 mode:development:设置webpack…...
iframe嵌入踩坑记录
iframe嵌入父子页面token问题 背景介绍 最近在做在平台A中嵌入平台B某个页面的需求,我负责的是平台B这边,使这个页面被嵌入后能正常使用。两个平台都实现了单点登录。 其实这是第二次做这个功能了,原本以为会很顺利,但没想到折腾…...
FreeRTOS——消息队列
目录 一、概念及其作用 1.1概念 1.2特点 1.3工作原理 二、相关API 2.1创建队列 2.2任务中写队列 2.3任务中读队列 2.4中断中写队列 2.5中断中读队列 三、实现原理 3.1消息队列控制块 3.2消息队列的创建 3.3消息的发送 3.3.1任务中发送 3.3.2中断中发送 3.4消息的…...
c++11的动态类型
c17引入了any 和 variant,可以将任意数据类型统一用any或variant类型表示,在开发中还是能够带来很多便利的。在c11版本中,可以用下面这个例子,仿照实现一个Any类型。 #include <iostream> #include <stdexcept> #inc…...
大语言模型---Llama模型文件介绍;文件组成
文章目录 1. 概要2. 文件组成 1. 概要 在使用 LLaMA(Large Language Model Meta AI)权重时,通常会涉及到与模型权重存储和加载相关的文件。这些文件通常是以二进制格式存储的,具有特定的结构来支持高效的模型操作。以下以Llama-7…...
常见网络厂商设备默认用户名/密码大全
常见网络厂商的默认用户名/密码 01 思科 (Cisco) 设备类型:路由器、交换机、防火墙、无线控制器 默认用户名:cisco 默认密码:cisco 设备类型:网管型交换机 默认用户名:admin 默认密码:admin 02 华…...
【大数据分析机器学习】分布式机器学习
【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈智能大数据分析 ⌋ ⌋ ⌋ 智能大数据分析是指利用先进的技术和算法对大规模数据进行深入分析和挖掘,以提取有价值的信息和洞察。它结合了大数据技术、人工智能(AI)、机器学习(ML&a…...
Go 语言已立足主流,编程语言排行榜24 年 11 月
Go语言概述 Go语言,简称Golang,是由Google的Robert Griesemer、Rob Pike和Ken Thompson在2007年设计,并于2009年11月正式宣布推出的静态类型、编译型开源编程语言。Go语言以其提高编程效率、软件构建速度和运行时性能的设计目标,…...
数字反向输出
数字反向输出 C语言代码C 代码Java代码Python代码 💐The Begin💐点点关注,收藏不迷路💐 小明听到广播里的数字后,总喜欢反着念给妈妈听。请聪明的你将小明听到的数字反向输出。 输入 输入为一个整型的四位数n 输出 …...
c++ std::stack总结
概念 std::stack 是 C 标准库中的一个容器适配器(Container Adapter)。它通常是基于其他容器(如 std::deque 或 std::vector)实现的,提供了一个后进先出(LIFO,Last In First Out)的…...
【C++习题】10.反转字符串中的单词 lll
题目: 链接🔗:557.反转字符串中的单词 lll 题目: 代码: class Solution { public:void Reverse(string &s, int start, int end){char tmp;while(start < end){tmp s[start];s[start] s[end];s[end] tmp;…...
【pyspark学习从入门到精通14】MLlib_1
目录 包的概览 加载和转换数据 在前文中,我们学习了如何为建模准备数据。在本文中,我们将实际使用这些知识,使用 PySpark 的 MLlib 包构建一个分类模型。 MLlib 代表机器学习库。尽管 MLlib 现在处于维护模式,即它不再积极开发…...
transformer.js(四): 模型接口介绍
前面的文章底层架构及性能优化指南介绍了transformer.js的架构和优化策略,在本文中,将详细介绍 transformer.js 的模型接口,帮助你了解如何在 JavaScript 环境中使用这些强大的工具。 推荐阅读 ansformer.js(二)&…...
java集合练习题
简答题:分析HashSet和treeSet分别如何去重的? TreeSet的去重机制: 如果你传入了一个Comparator匿名对象,就使用实现的compare去重,如果方法返回0,就认为是相同的元素/数据,就不添加,如果你没有传入一个Comp…...
微知-plantuml常用语法和要点以及模板?(note over、create、box,endbox、alt,else,end, autonumber)
文章目录 常见语法常用 线条类实线虚线斜箭头或奇数箭头 A ->(10) B: B->(10) A分割线:newpage 颜色类给箭头指定颜色 -[#red]->给某个note加颜色: note over Alice, Bob #FFAAAA: xxx给分组信息着色 alt#red 分组类alt xxx; else xxx; else xx…...
gitHub常用操作
gitHub常用操作 1、把项目拉下来2、添加上游仓库3、进入分支4、从上游仓库拉取更新 1、把项目拉下来 在对应项目的右上角点击fork,fork下来:将远程仓库复制到个人仓库 在创建好的分支文件夹下使用 git clone自己远程仓库下的http地址(fork…...
Mybatis Plus动态指定数据源
Java开发中一个项目连接多个数据源时,可能会有需要动态指定一个方法所使用的数据源的场景。例如不同的用户查询不同的数据源。 我遇到的需求是这样的:设计一个公共的数据字典组件,该组件需要连接数据源,使用方引入该组件后可以直…...
Python 爬虫 (1)基础 | 基础操作
一、基础操作 1、快速构建一个爬虫 ConvertCurl: https://curlconverter.com/选择URL,点击右键,选择 Copy >> Copy as cURL(bash) 安装JS环境:https://www.jb51.net/python/307069k7q.htm...
C++
目录 C 的发展总结:编辑 1. C 的早期发展(1979-1985) 2. C 标准化过程(1985-1998) 3. C 标准演化(2003-2011) 4. C11(2011年) 5. C14(2014年…...
Infineon(英飞凌) TLE985xQX 芯片电机工作电流、电压AD采样
其他系列文章导航 Java基础合集数据结构与算法合集 设计模式合集 多线程合集 分布式合集 单片机芯片合集 文章目录 其他系列文章导航 文章目录 前言 一、选取合适的端口 1.通过 OP1、OP2 电流采集运放输入端口进行H桥驱动的电流采集。 2.通过 O_D_VBAT_AD_EN、I_A_VBAT_A…...
三极管工作原理,以及小电流,如何驱动大电流
因为研究【自动下载电路实现】,涉及到三极管内容,之前看过,现在回看之前的笔记,一点印象都没了,于是,想了个办法,记住它 个人联想,不喜绕道,只是帮助个人记忆的 标题也是…...
Haystack 的开源开发 LLM 应用设计框架
每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…...
彻底理解消息队列的作用及如何选择
一.为什么要使用消息队列? 使用消息队列,其实是需要根据实际业务场景来的,一般都是实际开发中,遇到了某种技术挑战,如果不使用MQ的话,业务实现起来比较麻烦,但是通过MQ就可以更快捷高效的实现业…...
【Java】二叉树:数据海洋中灯塔式结构探秘(上)
个人主页 🌹:喜欢做梦 二叉树中有一个树,我们可以猜到他和树有关,那我们先了解一下什么是树,在来了解一下二叉树 一🍝、树型结构 1🍨.什么是树型结构? 树是一种非线性的数据结构&…...
海洋通信船舶组网工业4G路由器应用
船舶是浩瀚海洋中探索与贸易的载体,更是船员们生活与工作的家园。为了在广阔的水域中搭建起稳定、高效的网络桥梁,工业4G路由器以卓越的通信组网能力,为船舶组网提供网络支持。 工业4G路由器以其强大的信号发射能力,确保船舶内部…...
字符串-07-判断两个IP是否属于同一子网
文章目录 1. 题目描述2. 思路3. 代码 1. 题目描述 IP地址是由4个0-255之间的整数构成的,用"."符号相连。 二进制的IP地址格式有32位,例如:10000011,01101011,00000011,00011000;每八…...
Django启用国际化支持(2)—实现界面内切换语言:activate()
文章目录 ⭐注意⭐1. 配置项目全局设置:启用国际化2. 编写视图函数3. 配置路由4. 界面演示5、扩展自动识别并切换到当前语言设置语言并保存到Session设置语言并保存到 Cookie ⭐注意⭐ 以下操作依赖于 Django 项目的国际化支持。如果你不清楚如何启用国际化功能&am…...
自定义协议
1. 问题引入 问题:TCP是面向字节流的(TCP不关心发送的数据是消息、文件还是其他任何类型的数据。它简单地将所有数据视为一个字节序列,即字节流。这意味着TCP不会对发送的数据进行任何特定的边界划分,它只是确保数据的顺序和完整…...
PHP Date 函数:日期和时间处理的全指南
PHP Date 函数:日期和时间处理的全指南 PHP Date 函数是 PHP 编程语言中用于处理日期和时间的核心函数之一。它提供了强大的功能,允许开发者轻松地格式化、计算和操作日期和时间值。本文将详细介绍 PHP Date 函数的用法,包括基本格式化、时间戳处理、时区设置以及一些高级特…...
C++设计模式:抽象工厂模式(风格切换案例)
抽象工厂模式(Abstract Factory)是一种创建型设计模式,其核心思想是:为一组相关或相互依赖的对象提供一个创建接口,而无需指定它们具体的类。简单来说,就是一个工厂可以生产一系列相关的对象。 我们接下来…...
社交媒体营销新趋势:如何通过海外平台提升品牌曝光度?
社交媒体不仅是简单的信息传播工具,更是连接用户与品牌之间的重要纽带。每天,有数以亿计的全球用户在不同平台上活跃,潜藏着巨大的市场潜力。对于企业来说,关键在于制定清晰的营销策略,精准把握不同社交平台的特性&…...
嵌入式C/C++编译常见问题与分析
#1 kcx.c:112:89: error: format specifies type unsigned int but the argument has type u32 * (aka unsigned int *) [-Werror,-Wformat] 报错原因: int kcx(u32 *trigger) { ERR_MSG("%s:failed. attr%d, trigger%u\n", __func__, attr_enable, trig…...
laravel 5.5 增加宏指令 joinSub, 省去->toSql() 和 addBinding($bindings);
laravel 5.5 增加宏指令 joinSub, 省去->toSql() 和 addBinding($bindings); 1. 在laravel5使用join 子查询时 $sub_query DB::table(table1)->select([table1.id, cate_id])->join(table2, table1.id, , table2.id)->where(table1.cate_id, 2)->orderBy(tabl…...
知识库搭建:大健康产业数字化转型的新引擎
随着数字经济的蓬勃发展,大健康产业正步入一个崭新的发展篇章。消费者对于健康的追求日益增长,促使大健康企业积极探索数字化路径,以提升供应链效率、控制成本,并在激烈的市场竞争中脱颖而出。在此过程中,一系列数字化…...
创建可重用React组件的实用指南
尽管React是全球最受欢迎和使用最广泛的前端框架之一,但许多开发者在重构代码以提高可复用性时仍然感到困难。如果你发现自己在React应用中不断重复相同的代码片段,那你来对地方了。 在本教程中,将向你介绍三个最常见的特征,表明是…...
蓝桥杯每日真题 - 第18天
题目:(出差) 题目描述(13届 C&C B组E题) 解题思路: 问题分析 问题实质是一个带权图的最短路径问题,但路径的权重包含两个部分: 从当前城市到下一个城市的路程时间。 当前城市的…...
MySQL中索引全详解
第一部分:什么是索引 索引在数据库中就像书的目录,能够快速定位数据位置,从而提升查询效率。没有索引时,数据库查询需要从头到尾扫描整个表(称为全表扫描),这在数据量大时非常耗时。有了索引后&…...
探索复合物TPP-PEG-Heparin的特性;磷酸三苯酯-聚乙二醇-肝素的线粒体靶向性
TPP-PEG-Heparin,即磷酸三苯酯(TPP)、聚乙二醇(PEG)和肝素(Heparin)的复合物,其特性融合了这三种成分的性质。 一、线粒体靶向性 TPP部分:具有线粒体靶向功能…...
ubuntu 配置 多个 git 客户端 账户
Git配置两个或多个账户 https://blog.csdn.net/mainking2003/article/details/134711865 git 提交 不用输入用户名、密码的方法(GIT免密提交) https://blog.csdn.net/wowocpp/article/details/125797263 git config 用法 https://blog.csdn.net/blueb…...
Web3与智能合约:区块链技术下的数字信任体系
随着互联网的不断发展,Web3代表着我们迈入了一个去中心化、更加安全和智能的网络时代。作为Web3的核心组成部分,区块链技术为智能合约的出现和发展提供了强有力的基础。智能合约不仅仅是自动化的代码,它们正逐步成为重塑数字世界信任体系的关…...
RocketMQ文件刷盘机制深度解析与Java模拟实现
引言 在现代分布式系统中,消息队列(Message Queue, MQ)作为一种重要的中间件,扮演着连接不同服务、实现异步通信和消息解耦的关键角色。Apache RocketMQ作为一款高性能的分布式消息中间件,广泛应用于实时数据流处理、…...