【C++】封装红黑树实现的map和set
前言
这篇博客我们将上篇博客实现的红黑树来封装成自己实现的set和map,来模拟一下库里的map和set
💓 个人主页:小张同学zkf
⏩ 文章专栏:C++
若有问题 评论区见📝
🎉欢迎大家点赞👍收藏⭐文章
1.源码及框架分析
1 // set2 # ifndef __SGI_STL_INTERNAL_TREE_H3 # include <stl_tree.h>4 # endif5 # include <stl_set.h>6 # include <stl_multiset.h>78 // map9 # ifndef __SGI_STL_INTERNAL_TREE_H10 # include <stl_tree.h>11 # endif12 # include <stl_map.h>13 # include <stl_multimap.h>1415 // stl_set.h16 template < class Key , class Compare = less<Key>, class Alloc = alloc>17 class set {18 public :19 // typedefs:20 typedef Key key_type;21 typedef Key value_type;22 private :23 typedef rb_tree<key_type, value_type,24 identity<value_type>, key_compare, Alloc> rep_type;25 rep_type t; // red-black tree representing set26 };2728 // stl_map.h29 template < class Key , class T , class Compare = less<Key>, class Alloc = alloc>30 class map {31 public :32 // typedefs:33 typedef Key key_type;34 typedef T mapped_type;35 typedef pair< const Key, T> value_type;36 private :37 typedef rb_tree<key_type, value_type,38 select1st<value_type>, key_compare, Alloc> rep_type;39 rep_type t; // red-black tree representing map40 };4142 // stl_tree.h43 struct __rb_tree_node_base44 {45 typedef __rb_tree_color_type color_type;46 typedef __rb_tree_node_base* base_ptr;4748 color_type color;49 base_ptr parent;50 base_ptr left;51 base_ptr right;52 };5354 // stl_tree.h55 template < class Key , class Value , class KeyOfValue , class Compare , class Alloc= alloc>56 class rb_tree {57 protected :58 typedef void * void_pointer;59 typedef __rb_tree_node_base* base_ptr;60 typedef __rb_tree_node<Value> rb_tree_node;61 typedef rb_tree_node* link_type;62 typedef Key key_type;63 typedef Value value_type;64 public :65 // insert ⽤的是第⼆个模板参数左形参66 pair<iterator, bool > insert_unique ( const value_type& x);6768 // erase 和 find ⽤第⼀个模板参数做形参69 size_type erase ( const key_type& x);70 iterator find ( const key_type& x);71 protected :72 size_type node_count; // keeps track of size of tree73 link_type header;74 };7576 template < class Value >77 struct __rb_tree_node : public __rb_tree_node_base78 {79 typedef __rb_tree_node<Value>* link_type;80 Value value_field;81 };

2.模拟实现map和set
2.1实现出复⽤红⿊树的框架,并⽀持insert
// 源码中 pair ⽀持的 < 重载实现1template < class T1 , class T2 >2bool operator < ( const pair<T1,T2>& lhs, const pair<T1,T2>& rhs)3{ return lhs.first<rhs.first || (!(rhs.first<lhs.first) &&lhs.second<rhs.second); }45// Mymap.h6namespace zkf7{7template < class K , class V >8class map9{10struct MapKeyOfT11{12const K& operator ()( const pair<K, V>& kv)13{14return kv.first;15}16};17public :18bool insert ( const pair<K, V>& kv)19{20return _t . Insert (kv);21}22private :23RBTree<K, pair<K, V>, MapKeyOfT> _t ;24};25}26// Myset.h27namespace zkf28{29template < class K >33 class set34 {35 struct SetKeyOfT36 {37 const K& operator ()( const K& key)38 {39 return key;40 }41 };42 public :43 bool insert ( const K& key)44 {45 return _t . Insert (key);46 }47 private :48 RBTree<K, K, SetKeyOfT> _t ;49 };50 }5152 // RBTree.h53 enum Colour54 {55 RED,56 BLACK57 };5859 template < class T >60 struct RBTreeNode61 {62 T _data;6364 RBTreeNode<T>* _left;65 RBTreeNode<T>* _right;66 RBTreeNode<T>* _parent;67 Colour _col;6869 RBTreeNode ( const T& data)70 : _data(data)71 , _left( nullptr )72 , _right( nullptr )73 , _parent( nullptr )74 {}75 };7677 // 实现步骤:78 // 1 、实现红⿊树79 // 2 、封装 map 和 set 框架,解决 KeyOfT 80 // 3 、 iterator81 // 4 、 const_iterator82 // 5 、 key 不⽀持修改的问题83 // 6 、 operator[]84 template < class K , class T , class KeyOfT >85 class RBTree86 {87 private :88 typedef RBTreeNode<T> Node;89 Node* _root = nullptr ;9091 public :92 bool Insert ( const T& data)93 {94 if (_root == nullptr )95 {96 _root = new Node (data);97 _root->_col = BLACK;98 return true ;99 }100101 KeyOfT kot;102 Node* parent = nullptr ;103 Node* cur = _root;104 while (cur)105 {106 if ( kot (cur->_data) < kot (data))107 {108 parent = cur;109 cur = cur->_right;110 }111 else if ( kot (cur->_data) > kot (data))112 {113 parent = cur;114 cur = cur->_left;115 }116 else117 {118 return false ;119 }120 }121122 cur = new Node (data);123 Node* newnode = cur;124125 // 新增结点。颜⾊给红⾊126 cur->_col = RED; 127 if ( kot (parent->_data) < kot (data))128 {129 parent->_right = cur;130 }131 else132 {133 parent->_left = cur;134 }135 cur->_parent = parent;136137 //...138139 return true ;140 }141 }
2.2支持iterator实现
iterator核⼼源代码
1 struct __rb_tree_base_iterator2 {3 typedef __rb_tree_node_base::base_ptr base_ptr;4 base_ptr node;56 void increment ()7 {8 if (node->right != 0 ) {9 node = node->right;10 while (node->left != 0 )11 node = node->left;12 }13 else {14 base_ptr y = node->parent;15 while (node == y->right) {16 node = y;17 y = y->parent;18 }19 if (node->right != y)20 node = y;21 }22 }2324 void decrement ()25 { 26 if (node->color == __rb_tree_red &&27 node->parent->parent == node)28 node = node->right;29 else if (node->left != 0 ) {30 base_ptr y = node->left;31 while (y->right != 0 )32 y = y->right;33 node = y;34 }35 else {36 base_ptr y = node->parent;37 while (node == y->left) {38 node = y;39 y = y->parent;40 }41 node = y;42 }43 }44 };4546 template < class Value , class Ref , class Ptr >47 struct __rb_tree_iterator : public __rb_tree_base_iterator48 {49 typedef Value value_type;50 typedef Ref reference;51 typedef Ptr pointer;52 typedef __rb_tree_iterator<Value, Value&, Value*> iterator;53 __rb_tree_iterator() {}54 __rb_tree_iterator(link_type x) { node = x; }55 __rb_tree_iterator( const iterator& it) { node = it.node; }5657 reference operator *() const { return link_type (node)->value_field; }58 # ifndef __SGI_STL_NO_ARROW_OPERATOR59 pointer operator ->() const { return &( operator *()); }60 # endif /* __SGI_STL_NO_ARROW_OPERATOR */6162 self& operator ++() { increment (); return * this ; }63 self& operator --() { decrement (); return * this ; }6465 inline bool operator ==( const __rb_tree_base_iterator& x,66 const __rb_tree_base_iterator& y) {67 return x.node == y.node;68 }6970 inline bool operator !=( const __rb_tree_base_iterator& x,71 const __rb_tree_base_iterator& y) {72 return x.node != y.node;73 }
2.3map⽀持[]
// Myset.h# include "RBTree.h"namespace bit{template < class K >class set{struct SetKeyOfT{const K& operator ()( const K& key){return key;}};public :typedef typename RBTree<K, const K, SetKeyOfT>::Iterator iterator;typedef typename RBTree<K, const K, SetKeyOfT>::ConstIteratorconst_iterator;iterator begin (){return _t . Begin ();}iterator end (){return _t . End ();}const_iterator begin () const{return _t . Begin ();}const_iterator end () const{return _t . End ();}pair<iterator, bool > insert ( const K& key){42 return _t . Insert (key);43 }4445 iterator find ( const K& key)46 {47 return _t . Find (key);48 }4950 private :51 RBTree<K, const K, SetKeyOfT> _t ;52 };5354 void Print ( const set< int >& s)55 {56 set< int >::const_iterator it = s. end ();57 while (it != s. begin ())58 {59 --it;60 // 不⽀持修改61 //*it += 2;6263 cout << *it << " " ;64 }65 cout << endl;66 }6768 void test_set ()69 {70 set< int > s;71 int a[] = { 4 , 2 , 6 , 1 , 3 , 5 , 15 , 7 , 16 , 14 };72 for ( auto e : a)73 {74 s. insert (e);75 }7677 for ( auto e : s)78 {79 cout << e << " " ;80 }81 cout << endl;8283 Print (s);84 }85 }8687 // Mymap.h88 # include "RBTree.h" 89 namespace bit90 {91 template < class K , class V >92 class map93 {94 struct MapKeyOfT95 {96 const K& operator ()( const pair<K, V>& kv)97 {98 return kv.first;99 }100 };101 public :102 typedef typename RBTree<K, pair< const K, V>, MapKeyOfT>::Iteratoriterator;103 typedef typename RBTree<K, pair< const K, V>, MapKeyOfT>::ConstIteratorconst_iterator;104105 iterator begin ()106 {107 return _t . Begin ();108 }109110 iterator end ()111 {112 return _t . End ();113 }114115 const_iterator begin () const116 {117 return _t . Begin ();118 }119120 const_iterator end () const121 {122 return _t . End ();123 }124125 pair<iterator, bool > insert ( const pair<K, V>& kv)126 {127 return _t . Insert (kv);128 }129130 iterator find ( const K& key)131 {132 return _t . Find (key);133 } 134135 V& operator []( const K& key)136 {137 pair<iterator, bool > ret = insert ( make_pair (key, V ()));138 return ret.first->second;139 }140141 private :142 RBTree<K, pair< const K, V>, MapKeyOfT> _t ;143 };144145 void test_map ()146 {147 map<string, string> dict;148 dict. insert ({ "sort" , " 排序 " });149 dict. insert ({ "left" , " 左边 " });150 dict. insert ({ "right" , " 右边 " });151152 dict[ "left" ] = " 左边,剩余 " ;153 dict[ "insert" ] = " 插⼊ " ;154 dict[ "string" ];155156 map<string, string>::iterator it = dict. begin ();157 while (it != dict. end ())158 {159 // 不能修改 first ,可以修改 second160 //it->first += 'x';161 it->second += 'x' ;162163 cout << it->first << ":" << it->second << endl;164 ++it;165 }166 cout << endl;167 }168 }169170 // RBtree.h171 enum Colour172 {173 RED,174 BLACK175 };176177 template < class T >178 struct RBTreeNode179 {180 T _data; 181182 RBTreeNode<T>* _left;183 RBTreeNode<T>* _right;184 RBTreeNode<T>* _parent;185 Colour _col;186187 RBTreeNode ( const T& data)188 : _data(data)189 , _left( nullptr )190 , _right( nullptr )191 , _parent( nullptr )192 {}193 };194195 template < class T , class Ref , class Ptr >196 struct RBTreeIterator197 {198 typedef RBTreeNode<T> Node;199 typedef RBTreeIterator<T, Ref, Ptr> Self;200201 Node* _node;202 Node* _root;203204 RBTreeIterator (Node* node, Node* root)205 :_node(node)206 ,_root(root)207 {}208209 Self& operator ++()210 {211 if (_node->_right)212 {213 // 右不为空,右⼦树最左结点就是中序第⼀个214 Node* leftMost = _node->_right;215 while (leftMost->_left)216 {217 leftMost = leftMost->_left;218 }219220 _node = leftMost;221 }222 else223 {224 // 孩⼦是⽗亲左的那个祖先225 Node* cur = _node;226 Node* parent = cur->_parent;227 while (parent && cur == parent->_right) 228 {229 cur = parent;230 parent = cur->_parent;231 }232233 _node = parent;234 }235236 return * this ;237 }238239 Self& operator --()240 {241 if (_node == nullptr ) // end()242 {243 // --end() ,特殊处理,⾛到中序最后⼀个结点,整棵树的最右结点244 Node* rightMost = _root;245 while (rightMost && rightMost->_right)246 {247 rightMost = rightMost->_right;248 }249250 _node = rightMost;251 }252 else if (_node->_left)253 {254 // 左⼦树不为空,中序左⼦树最后⼀个255 Node* rightMost = _node->_left;256 while (rightMost->_right)257 {258 rightMost = rightMost->_right;259 }260261 _node = rightMost;262 }263 else264 {265 // 孩⼦是⽗亲右的那个祖先266 Node* cur = _node;267 Node* parent = cur->_parent;268 while (parent && cur == parent->_left)269 {270 cur = parent;271 parent = cur->_parent;272 }273274 _node = parent; 275276 }277278 return * this ;279 }280281 Ref operator *()282 {283 return _node->_data;284 }285286 Ptr operator ->()287 {288 return &_node->_data;289 }290291 bool operator != ( const Self& s) const292 {293 return _node != s._node;294 }295296 bool operator == ( const Self& s) const297 {298 return _node == s._node;299 }300 };301302 template < class K , class T , class KeyOfT >303 class RBTree304 {305 typedef RBTreeNode<T> Node;306 public :307 typedef RBTreeIterator<T, T&, T*> Iterator;308 typedef RBTreeIterator<T, const T&, const T*> ConstIterator;309310 Iterator Begin ()311 {312 Node* leftMost = _root;313 while (leftMost && leftMost->_left)314 {315 leftMost = leftMost->_left;316 }317318 return Iterator (leftMost, _root);319 }320321 Iterator End () 322 {323 return Iterator ( nullptr , _root);324 }325326 ConstIterator Begin () const327 {328 Node* leftMost = _root;329 while (leftMost && leftMost->_left)330 {331 leftMost = leftMost->_left;332 }333334 return ConstIterator (leftMost, _root);335 }336337 ConstIterator End () const338 {339 return ConstIterator ( nullptr , _root);340 }341342 RBTree () = default ;343344 RBTree ( const RBTree& t)345 {346 _root = Copy (t._root);347 }348349 RBTree& operator =(RBTree t)350 {351 swap (_root, t._root);352 return * this ;353 }354355 ~ RBTree ()356 {357 Destroy (_root);358 _root = nullptr ;359 }360361 pair<Iterator, bool > Insert ( const T& data)362 {363 if (_root == nullptr )364 {365 _root = new Node (data);366 _root->_col = BLACK;367 return make_pair ( Iterator (_root, _root), true );368 }369370 KeyOfT kot;371 Node* parent = nullptr ;372 Node* cur = _root;373 while (cur)374 {375 if ( kot (cur->_data) < kot (data))376 {377 parent = cur;378 cur = cur->_right;379 }380 else if ( kot (cur->_data) > kot (data))381 {382 parent = cur;383 cur = cur->_left;384 }385 else386 {387 return make_pair ( Iterator (cur, _root), false );388 }389 }390391 cur = new Node (data);392 Node* newnode = cur;393394 // 新增结点。颜⾊红⾊给红⾊395 cur->_col = RED;396 if ( kot (parent->_data) < kot (data))397 {398 parent->_right = cur;399 }400 else401 {402 parent->_left = cur;403 }404 cur->_parent = parent;405406 while (parent && parent->_col == RED)407 {408 Node* grandfather = parent->_parent;409 // g410 // p u411 if (parent == grandfather->_left)412 {413 Node* uncle = grandfather->_right;414 if (uncle && uncle->_col == RED)415 { 416 // u 存在且为红 - 》变⾊再继续往上处理417 parent->_col = uncle->_col = BLACK;418 grandfather->_col = RED;419420 cur = grandfather;421 parent = cur->_parent;422 }423 else424 {425 // u 存在且为⿊或不存在 - 》旋转 + 变⾊426 if (cur == parent->_left)427 {428 // g429 // p u430 //c431 // 单旋432 RotateR (grandfather);433 parent->_col = BLACK;434 grandfather->_col = RED;435 }436 else437 {438 // g439 // p u440 // c441 // 双旋442 RotateL (parent);443 RotateR (grandfather);444445 cur->_col = BLACK;446 grandfather->_col = RED;447 }448449 break ;450 }451 }452 else453 {454 // g455 // u p456 Node* uncle = grandfather->_left;457 // 叔叔存在且为红, - 》变⾊即可458 if (uncle && uncle->_col == RED)459 {460 parent->_col = uncle->_col = BLACK;461 grandfather->_col = RED;462 463 // 继续往上处理464 cur = grandfather;465 parent = cur->_parent;466 }467 else // 叔叔不存在,或者存在且为⿊468 {469 // 情况⼆:叔叔不存在或者存在且为⿊470 // 旋转 + 变⾊471 // g472 // u p473 // c474 if (cur == parent->_right)475 {476 RotateL (grandfather);477 parent->_col = BLACK;478 grandfather->_col = RED;479 }480 else481 {482 // g483 // u p484 // c485 RotateR (parent);486 RotateL (grandfather);487 cur->_col = BLACK;488 grandfather->_col = RED;489 }490 break ;491 }492 }493 }494495 _root->_col = BLACK;496497 return make_pair ( Iterator (newnode, _root), true );498 }499500 Iterator Find ( const K& key)501 {502 Node* cur = _root;503 while (cur)504 {505 if (cur->_kv.first < key)506 {507 cur = cur->_right;508 }509 else if (cur->_kv.first > key) 510 {511 cur = cur->_left;512 }513 else514 {515 return Iterator (cur, _root);516 }517 }518519 return End ();520 }521522 private :523 void RotateL (Node* parent)524 {525 Node* subR = parent->_right;526 Node* subRL = subR->_left;527528 parent->_right = subRL;529 if (subRL)530 subRL->_parent = parent;531532 Node* parentParent = parent->_parent;533534 subR->_left = parent;535 parent->_parent = subR;536537 if (parentParent == nullptr )538 {539 _root = subR;540 subR->_parent = nullptr ;541 }542 else543 {544 if (parent == parentParent->_left)545 {546 parentParent->_left = subR;547 }548 else549 {550 parentParent->_right = subR;551 }552553 subR->_parent = parentParent;554 }555 }556 557 void RotateR (Node* parent)558 {559 Node* subL = parent->_left;560 Node* subLR = subL->_right;561562 parent->_left = subLR;563 if (subLR)564 subLR->_parent = parent;565566 Node* parentParent = parent->_parent;567568 subL->_right = parent;569 parent->_parent = subL;570571 if (parentParent == nullptr )572 {573 _root = subL;574 subL->_parent = nullptr ;575 }576 else577 {578 if (parent == parentParent->_left)579 {580 parentParent->_left = subL;581 }582 else583 {584 parentParent->_right = subL;585 }586587 subL->_parent = parentParent;588 }589590 }591592 void Destroy (Node* root)593 {594 if (root == nullptr )595 return ;596597 Destroy (root->_left);598 Destroy (root->_right);599 delete root;600 }601602 Node* Copy (Node* root)603 { 604 if (root == nullptr )605 return nullptr ;606607 Node* newRoot = new Node (root->_kv);608 newRoot->_left = Copy (root->_left);609 newRoot->_right = Copy (root->_right);610611 return newRoot;612 }613614 private :615 Node* _root = nullptr ;616 };
结束语
map和set详细知识这几篇博客算是总结完了,下片博客看看unordered_set和unordered_map.
本篇博客结束,感谢观看。
相关文章:
【C++】封装红黑树实现的map和set
前言 这篇博客我们将上篇博客实现的红黑树来封装成自己实现的set和map,来模拟一下库里的map和set 💓 个人主页:小张同学zkf ⏩ 文章专栏:C 若有问题 评论区见📝 🎉欢迎大家点赞👍收藏⭐文章 1.源…...
【SSM】mybatis的增删改查
目录 代理Dao方式的增删改查 1. 创建项目 $$1. 在sql.xml里增加日志代码以及user的mapper资源。 $$ 2. 在usermapper里引入接口。 $$3. 在测试类中引入以下代码,并修改其中名字。 $$ 4. 实例对象User.java里属性要与表中列严格对应。 2. 查询 1>. 查询所有 …...
macos下brew安装redis
首先确保已安装brew,接下来搜索资源,在终端输入如下命令: brew search redis 演示如下: 如上看到有redis资源,下面进行安装,执行下面的命令: brew install redis 演示效果如下: …...
鸿蒙修饰符
文章目录 一、引言1.1 什么是修饰符1.2 修饰符在鸿蒙开发中的重要性1.3 修饰符的作用机制 二、UI装饰类修饰符2.1 Styles修饰符2.1.1 基本概念和使用场景2.1.2 使用示例2.1.3 最佳实践 2.2 Extend修饰符2.2.1 基本概念2.2.2 使用示例2.2.3 Extend vs Styles 对比2.2.4 使用建议…...
【Linux】Linux2.6内核进程调度队列与调度原理
目录 一、进程管理中的部分概念二、寄存器三、进程切换四、Linux2.6内核进程调度队列与调度原理结尾 一、进程管理中的部分概念 竞争性: 系统进程数目众多,而CPU资源只有少量,甚至1个,所以进程之间是具有竞争属性的。为了高效完成任务&#…...
MacOS使用VSCode编写C++程序如何配置clang编译环境
前言 这段时间在练习写C和Python,用vscode这个开发工具,调试的时候遇到一些麻烦,浪费了很多时间,因此整理了这个文档。将详细的细节描述清楚,避免与我遇到同样问题的人踩坑。 1.开发环境的配置 vscode的开发环境配置…...
【Spark源码分析】规则框架- `analysis`分析阶段使用的规则
analysis分析阶段使用的规则 规则批策略规则说明SubstitutionfixedPointOptimizeUpdateFields该规则优化了 UpdateFields 表达式链,因此看起来更像优化规则。但是,在处理深嵌套模式时,UpdateFields 表达式树可能会非常复杂,导致分…...
Windows和Ubuntu系统下cmake和opencv的安装和使用
以下是在Windows和Ubuntu系统下分别安装CMake并使用C配置OpenCV实现读取图片并显示功能的详细步骤: Windows系统 1. 安装CMake 访问CMake官方网站(https://cmake.org/download/)。根据你的Windows系统版本(32位或64位ÿ…...
详解 Qt QtPDF之QPdfPageNavigator 页面跳转
文章目录 前言头文件: 自 Qt 6.4 起继承自: 属性backAvailable : const boolcurrentLocation : const QPointFcurrentPage : const intcurrentZoom : const qrealforwardAvailable : const bool 公共函数QPdfPageNavigator(QObject *parent)virtual ~QPd…...
设计模式之单例
单例可以说是设计模式中最简单的一种模式。但任何一种设计模式都是普遍经验的总结,都有值得思考的地方。所以单例也并不简单,下面让我们慢慢了解它。 单例顾名思义这个类只有一个实例。要做到这点,需要做到以下几点: (…...
笔记软件:我来、思源笔记、Obsidian、OneNote
最近wolai的会员到期了,促使我更新了一下笔记软件。 首先,wolai作为一个笔记软件,我觉得有很多做得不错的方面(否则我也不会为它付费2年了),各种功能集成得很全(公式识别这个功能我写论文的时候…...
前端入门指南:前端模块有哪些格式?分别什么情况使用
前言 在当今的前端开发中,模块化是提升代码组织性和可维护性的关键手段。随着前端技术的发展,出现了多种模块化方案,每种方案都有其独特的优势和适用场景。本文将详细探讨常见的前端模块格式,包括全局变量、IIFE、CommonJS、AMD、…...
Vue3 常用指令解析:v-bind、v-if、v-for、v-show、v-model
Vue 是一个非常强大的前端框架,提供了许多常用指令来简化模板的使用。Vue 指令以 v- 开头,用于对 DOM 元素和组件的行为进行控制。本文将介绍 Vue 中常见的五个指令:v-bind、v-if、v-for、v-show 和 v-model,并通过实例代码来演示…...
如何查看ubuntu服务器的ssh服务是否可用
你可以通过以下几种方法检查 Ubuntu 服务器上的 SSH 服务是否可用: 1. 使用 systemctl 检查 SSH 服务状态 首先,检查 SSH 服务是否正在运行: sudo systemctl status ssh如果 SSH 服务正在运行,你会看到类似以下的输出ÿ…...
redis面试复习
1.redis是单线程还是多线程 无论什么版本工作线程就是是一个,6.x高版本出现了IO多线程 单线程满足redis的串行原子,只不过IO多线程后,把输入/输出放到更多的线程里区并行,好处: 1.执行的时间更短,更快&a…...
【人工智能基础04】线性模型
文章目录 一. 基本知识1. 线性回归1.1. 基本形式1.2. 线性回归 2. 优化方法:梯度下降法2.1. 梯度下降法的直观意义2.2. 随机梯度下降法 3. 分类问题3.1. 二分类:逻辑回归-sigmoid函数3.2. 多分类问题--softmax函数 4. 岭回归与套索回归4.1. 基础概念什么…...
使用YOLO系列txt目标检测标签的滑窗切割:批量处理图像和标签的实用工具
使用YOLO系列txt目标检测标签的滑窗切割:批量处理图像和标签的实用工具 使用YOLO的TXT目标检测标签的滑窗切割:批量处理图像和标签的实用工具背景1. 代码概述2. 滑窗切割算法原理滑窗切割步骤:示例: 3. **代码实现**1. **加载标签…...
《装甲车内气体检测“神器”:上海松柏 K-5S 电化学传感器模组详解》
《装甲车内气体检测“神器”:上海松柏 K-5S 电化学传感器模组详解》 一、引言二、K-5S 电化学传感器模组概述(一)产品简介(二)产品特点(三)产品适用场景 三、电化学传感器原理及优点(一…...
【笔记】文明、现代化与价值投资
文章目录 价值投资与理性思考资管行业特点及对从业人员的道德底线要求价值投资长期来看,各项资产的走势投资与投机 对文明的认知对文明的计量方式狩猎文明或1.0文明农业畜牧文明或2.0文明农业文明的天花板及三次冲顶农业文明中的思想革命和制度创新 科技文明或3.0文…...
排序学习整理(1)
1.排序的概念及运用 1.1概念 排序:所谓排序,就是使⼀串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作,以便更容易查找、组织或分析数据。 1.2运用 购物筛选排序 院校排名 1.3常见排序算法 2.实…...
提升分布式系统响应速度:分布式系统远程调用性能提升之道
目录 一、远程调用直接案例分析 二、并行调用 (一)核心思想 (二)并行调用的实现方式 1. 基本思路 2. 代码示例 3. 关键点说明 4.线程池配置建议 三、数据异构 (一)场景重提 (二&…...
通过MinIO+h2non/imaginary 搭建自己的阿里云OSS
安装MinIO Docker部署MinIO对象存储服务 图片访问地址:http://192.168.153.138:9000/public/su7_1.jpg 安装h2non/imaginary Docker部署h2non/imaginary 处理图片地址:http://192.168.153.138:7000/resize?urlhttp://192.168.153.138:9000/public/su…...
.NET 9 AOT的突破 - 支持老旧Win7与XP环境
引言 随着技术的不断进步,微软的.NET 框架在每次迭代中都带来了令人惊喜的新特性。在.NET 9 版本中,一个特别引人注目的亮点是 AOT( Ahead-of-Time)支持,它允许开发人员将应用程序在编译阶段就优化为能够在老旧的 Win…...
iOS与Windows间传文件
想用数据线从 windows 手提电脑传文件入 iPhone,有点迂回。 参考 [1],要在 windows 装 Apple Devices。装完、打开、插线之后会检测到手机,界面: 点左侧栏「文件」,不是就直接可以传,而是要通过某个应用传…...
ospf协议(动态路由协议)
ospf基本概念 定义 OSPF 是典型的链路状态路由协议,是目前业内使用非常广泛的 IGP 协议之一。 目前针对 IPv4 协议使用的是 OSPF Version 2 ( RFC2328 );针对 IPv6 协议使用 OSPF Version 3 ( RFC2740 )。…...
直击高频编程考点:聚焦新版综合编程能力考查汇总
目录 一、业务性编程和广度能力考查 (一)基本定义 (二)必要性分析 二、高频考查样题(编程扩展问法) 考题1: 用java 代码实现一个死锁用例,说说怎么解决死锁问题?(高…...
爬虫框架快速入门——Scrapy
适用人群:零基础、对网络爬虫有兴趣但不知道从何开始的小白。 什么是 Scrapy? Scrapy 是一个基于 Python 的网络爬虫框架,它能帮助你快速爬取网站上的数据,并将数据保存到文件或数据库中。 特点: 高效:支…...
Springfox、Swagger 和 Springdoc
Springfox、Swagger 和 Springdoc 是用于在 Spring Boot 项目中生成 API 文档的工具,但它们之间有显著的区别和演进关系: 1. Swagger 简介 Swagger 是一个开源项目,旨在为 RESTful APIs 提供交互式文档。最早由 SmartBear 开发,…...
Css、less和Sass(SCSS)的区别详解
文章目录 Css、less和Sass(SCSS)的区别详解一、引言二、CSS 简介1.1、CSS 示例 三、Less 简介2.1、Less 特性2.2、Less 示例 四、Sass(SCSS)简介3.1、Sass 特性3.2、SCSS 示例 五、总结 Css、less和Sass(SCSSÿ…...
新能源汽车充电基础设施短板问题多,如何实现高效、综合、智能化管理?
随着城市经济的发展,人民生活水平的提升,新能源汽车保有量快速增长,而日益增长的新能源汽车需求与充电基础设施建设不平衡的矛盾日益突出。由于停车泊位充电基础设施总量不足、布局待优化、利用效率低、建设运营存在短板问题等原因࿰…...
DBA面试题-1
面临失业,整理一下面试题,找下家继续搬砖 主要参考:https://www.csdn.net/?spm1001.2101.3001.4476 略有修改 一、mysql有哪些数据类型 1, 整形 tinyint,smallint,medumint,int,bigint;分别占用1字节、2字节、3字节…...
LAN,WAN,VLAN,WLAN,VPN了解笔记
局域网LAN---公司的内部网络就是局域网LAN。 提供有线连接的接口允许局域网内的设备(如台式电脑、网络打印机、网络存储设备等)通过以太网线连接到路由器并与其他局域网设备进行通信实现设备之间的数据传输和资源共享一种私有的网络相对其他网络传输速度…...
1.2 算法和算法评价
1.2.1 算法的基本概念 算法:对特定问题求解步骤的一种描述,它是指令的有限序列,其中的每条指令表示一个或多个操作。 算法的五个重要特性 “好”的算法的五个目标 1.2.2 算法效率的度量 一、时间复杂度 算法的时间复杂度是指一个算法每行…...
各大常见编程语言应用领域
不同编程语言因其特性和设计目标而适用于不同的应用领域。以下是一些常见编程语言及其主要应用领域: 1. Python 数据科学与人工智能:Python 在数据分析、机器学习、深度学习等领域广泛使用,因其丰富的库(如 NumPy、Pandas、Tens…...
【FFT】数据点数是否一定为2的n次方?不补零会如何处理?
一般来说,FFT的数据点个数为以2为基数的整数次方(采用以2为基的FFT算法,可以提升运算性能),但是并没有要求FFT的数据点个数一定为2的n次方。 因此针对数据点数不是以2为基数的整数次方,有两种处理方法&…...
shell脚本小练习#003:查找并拷贝目录
实例1: # 从当前执行脚本的路径位置开始向上搜索一个名为sourceProject目录名 # 并将这个文件目录的路径名称打印出来#!/bin/bashfunction find_dir() {local current_dir$PWDwhile [[ $current_dir ! "/" ]]; doif [[ -d "${current_dir}/sourcePr…...
frp内网穿透
目录 1,准备公网服务器 2,下载安装frp服务端 3,服务端安装 2)编辑服务端配置文件fprs.toml 3)配置启动服务 4)启动服务 5 )设置开机启动服务 6)查看服务启动状态 3,…...
Android电视项目焦点跨层级流转
1. 背景 在智家电视项目中,主要操作方式不是触摸,而是遥控器,通过Focus进行移动,确定点击进行的交互,所以在电视项目中焦点、选中、确定、返回这几个交互比较重要。由于电视屏比较大,在一些复杂页面中会存…...
时频转换 | Matlab基于S变换S-transform一维数据转二维图像方法
目录 基本介绍程序设计参考资料获取方式基本介绍 时频转换 | Matlab基于S变换S-transform一维数据转二维图像方法 程序设计 clear clc % close all load x.mat % 导入数据 x =...
转载 为nautilus安装rabbitvcs
# 添加 rabbitvcs 的 ppa 源 sudo add-apt-repository ppa:rabbitvcs/ppa sudo apt update # 安装 rabbitvcs sudo apt install rabbitvcs-cli rabbitvcs-core rabbitvcs-gedit rabbitvcs-nautilus # 注销后重新登录,右键即可使用 # 解决 RabbitVCS 无法自动保存…...
OpenCV 模板匹配全解析:从单模板到多模板的实战指南
简介:本文深入探讨 OpenCV 中的模板匹配技术。详细介绍构建输入图像与模板图像的步骤,包括读取、截取、滤波与存储等操作。剖析 cv2.matchTemplate 语法及其参数含义,阐述不同匹配方法下结果值的意义。同时讲解 cv2.minMaxLoc 语法࿰…...
手机控制载货汽车一键启动无钥匙进入广泛应用
移动管家载货汽车一键启动无钥匙进入手机控车系统, 该系统广泛应用于物流运输、工程作业等货车场景,为车主提供了高效、便捷的启动和熄火解决方案,体现了科技进步对物流行业的积极影响 核心功能:简化启动流程,提…...
Springboot——SseEmitter流式输出
文章目录 前言SseEmitter 简介测试demo注意点异常一 ResponseBodyEmitter is already set complete 前言 最近做AI类的开发,看到各大AI模型的输出方式都是采取的一种EventStream的方式实现。 不是通常的等接口处理完成后,一次性返回。 而是片段式的处理…...
【人工智能数学基础篇】线性代数基础学习:深入解读矩阵及其运算
矩阵及其运算:人工智能入门数学基础的深入解读 引言 线性代数是人工智能(AI)和机器学习的数学基础,而矩阵作为其核心概念之一,承担着数据表示、变换和运算的重任。矩阵不仅在数据科学中广泛应用,更是神经…...
idea 自动导包,并且禁止自动导 *(java.io.*)
自动导包配置 进入 idea 设置,可以按下图所示寻找位置,也可以直接输入 auto import 快速定位到配置。 Add unambiguous imports on the fly:自动帮我们优化导入的包Optimize imports on the fly:自动去掉一些没有用到的包 禁止导…...
奇怪的编码2
1.当铺密码 当铺密码的标志是“田由中人工大王夫井羊” 口 0 田 0 由 1 中 2 人 3 工 4 大 5 王 6 夫 7 井 8 羊 9 解密脚本: s 田由中人工大王夫井羊 codeinput("请输入当铺密码:") code code.split(" ") w for i in code:k…...
AI服务器从HBM到CXL的技术变革
AI服务器从HBM到CXL变革 本文探讨了AI产业的新范式,特别是服务器变革。传统服务器价格通常在1万美金以内,而搭载8张H100算力卡的DGX H100AI服务器价值高达40万美金(约300万人民币)。这一变化将对AI产业产生深远影响。 自然语言和图形处理依赖大量存储器…...
将自定义 AWS S3 快照存储库连接到 Elastic Cloud
作者:来自 Elastic Annie Hansen, Stef Nestor 在本博客中,我们将介绍如何通过 Elasticsearch 的快照将我们已提交的集群数据备份到 AWS S3 存储桶中。在 Elastic Cloud(企业版)中,Elastic 在其 found-snapshots 存储…...
Java 多线程编程核心要点全解析:深度探秘关键方法与同步机制
1.Thread 类中的start() 和 run() 方法有什么区别? 在Java编程语言中,Thread 类的 start() 和 run() 方法有重要的区别: start() 方法: 当你调用 start() 方法时,它会启动一个新的线程,并且这个新线程会…...
个人博客接入github issue风格的评论,utteranc,gitment
在做个人博客的时候,如果你需要评论功能,但是又不想构建用户体系和评论模块,那么可以直接使用github的issue提供的接口,对应的开源项目有utteranc和gitment,尤其是前者。 它们的原理是一样的:在博客文章下…...