当前位置: 首页 > news >正文

移情别恋c++ ദ്ദി˶ー̀֊ー́ ) ——13.mapset(模拟实现)

1.对红黑树进行改造

1.1treenode模板参数改变

之前构建treenode模板参数传的是class k,class v(set为k,k;map是k,v),现在直接用T代替

template<class T>  //这里直接传了T作为模板参数,T可能是pair<k,t>,也可能是k
struct RBTtreenode
{RBTtreenode<T>* _left;RBTtreenode<T>* _right;RBTtreenode<T>* _parent;//pair<K, V> kv;T data;color col;RBTtreenode(const T& _data):_left(nullptr), _right(nullptr), _parent(nullptr), data(_data), col(RED){}
};

 

2.构建红黑树的迭代器 

因为要构建const_iterator(不可修改内容) 和iterator(可修改内容)所以需要三个模板参数

//<T,T&,T*> iterator;//普通迭代器
//<T, const T&, const T*> const_iterator;//指向的东西不能改变

template<class T,class Ref,class Ptr>

 iterator内存的是node*类型的数据!!!!

2.1 重载operator*()   (set)

因为set传模板参数只传K,没有Vdata类型是K,

所以用*直接取得data即可

Ref operator*()
{return _node->data;
}

 2.2 重载operator->()   (map)

因为map模板参数传的是K,pair<const K,T>,data类型是pair<const K,T>

想取到K,则需要传回&data,再用->first取得K

Ptr operator->()
{return &_node->data;
}

 2.3operator++()与operator--()

 这里以operator++()做解释:

分三种情况:

1.如果右子树不为空,则找到右子树的最左节点

2.//如果右子树为空,且cur是parent的右子树,则先parent回溯至parent->_parent,再_node变为parent
3.//如果右子树为空,且cur是parent的左子树,则_node变为parent

 

iterator& operator++()
{if (_node->_right){//如果右子树不为空,则找到右子树的最左节点node* cur = _node->_right;while (cur && cur->_left){cur = cur->_left;}_node = cur;}else{//如果右子树为空,且cur是parent的右子树,则先parent回溯至parent->_parent,再_node变为parent//如果右子树为空,且cur是parent的左子树,则_node变为parentnode* cur = _node;node* parent = cur->_parent;while (parent && cur == parent->_right){cur = parent;parent = parent->_parent;}_node = parent;}return *this;
}

2.4.begin()&&end() 

iterator begin()
{node* flag = root;while (flag&&flag->_left)//flag可能为nullptr{flag = flag->_left;}return iterator(flag);
}iterator end()
{return iterator(nullptr); //end用nullptr去构造!!!!!!!!
}const_iterator begin() const
{node* flag = root;while (flag && flag->_left)//flag可能为nullptr{flag = flag->_left;}return const_iterator(flag);
}const_iterator end() const
{return const_iterator(nullptr); //end用nullptr去构造!!!!!!!!
}

3.set.h封装

https://cplusplus.com/reference/set/set/?kw=set

#include"rbt.h"
namespace zone
{template<class K>class set{public:struct setkeyoft //仿函数,用来取出红黑树节点data中的key{const K& operator()(const K& key){return key;}};//set这里的迭代器本质都是const_iterator,因为k要求无法修改typedef typename RBTtree<K, K, setkeyoft>::const_iterator iterator;//记得要使用typename告诉编译器RBTtree<K, K, setkeyoft>::iterator这个是类型,不是函数typedef typename RBTtree<K, K, setkeyoft>::const_iterator const_iterator;iterator begin()const{return it.begin();}iterator end()const{return it.end();}pair<iterator,bool> insert(const K& key){return it.insert(key);}void inorder(){it.inorder();}private:RBTtree<K,K,setkeyoft> it;};
}

3.1 仿函数setkeyoft

仿函数,用来取出红黑树节点data中的key,用于insert函数!!!!

3.2 iterator和const_iterator

//set这里的迭代器本质都是const_iterator,因为k要求无法修改
        typedef typename RBTtree<K, K, setkeyoft>::const_iterator iterator;
        typedef typename RBTtree<K, K, setkeyoft>::const_iterator const_iterator;

4.map.h封装 

https://cplusplus.com/reference/map/map/?kw=map

#include"rbt.h"
namespace zone
{template<class K,class T>class map{public:struct setkeyoft{const K& operator()(const pair<K, T>& key){return key.first;}};//map这里的迭代器则使用的是iterator,因为k要求无法修改,但v可以修改,所以可以直接初始化时用pair<const K, T>typedef typename RBTtree<K, pair<const K, T>, setkeyoft>::iterator iterator;typedef typename RBTtree<K, pair<const K, T>, setkeyoft>::const_iterator const_iterator;pair<iterator, bool> insert(const pair<K, T>& key){return it.insert(key);}T& operator[](const K& key){pair<iterator, bool>ret = insert(make_pair(key,T()));//insert返回一个pair,first是iterator,second是bool类型return ret.first->second;}iterator begin(){return it.begin();}iterator end(){return it.end();}void inorder(){it.inorder();}private:RBTtree<K,pair<const K,T>, setkeyoft> it;};
}

5.insert函数 !!!!!!!

RBT.h里insert函数的返回值是 pair<node*, bool>

但封装过后的map.h,set.h里

pair<iterator,bool> insert(const K& key)
{return it.insert(key);
}

 返回值是pair<iterator,bool>

可见 pair<node*, bool>pair<iterator(这里的iterator已经重命名了,本质是const_iteratir),bool>并不是同一类型,该如何解决呢?

 

 

1.如果T1和U类型一致,T2和V类型一致,那么就是拷贝构造!!!

2.如果不一致,也可以进行普通构造前提是有可以用first来构建T1的函数!!!!!

回到刚才的问题:

可见 pair<node*, bool>pair<iterator(这里的iterator已经重命名了,本质是const_iteratir),bool>并不是同一类型,该如何解决呢?

bool类型肯定可以用bool类型初始化,

iterator可以用node*进行初始化吗?

答案是可以的

treeiterator(node* it):_node(it)
{}

相当于使用了隐式类型转换

 6.杂谈

 

类比指针:

1.iterator 可修改指向的数据,也可改变自身

2.const iterator  可修改指向的数据,但不可改变自身

3.const_iterator 不可修改指向的数据,但能改变自身

 7.代码全览

RBT.h

#include<iostream>using namespace std;enum color
{RED,BLACK
};  //列举color的各种可能情况template<class T>  //这里直接传了T作为模板参数,T可能是pair<k,t>,也可能是k
struct RBTtreenode
{RBTtreenode<T>* _left;RBTtreenode<T>* _right;RBTtreenode<T>* _parent;//pair<K, V> kv;T data;color col;RBTtreenode(const T& _data):_left(nullptr), _right(nullptr), _parent(nullptr), data(_data), col(RED){}
};//<T,T&,T*> iterator;//普通迭代器
//<T, const T&, const T*> const_iterator;//指向的东西不能改变:const_iterator,本身不能改变:const iterator
template<class T,class Ref,class Ptr>
struct treeiterator
{typedef RBTtreenode<T> node;typedef treeiterator<T,Ref,Ptr> iterator;node* _node;treeiterator(node* it):_node(it){}Ref operator*(){return _node->data;}Ptr operator->(){return &_node->data;}iterator& operator++(){if (_node->_right){//如果右子树不为空,则找到右子树的最左节点node* cur = _node->_right;while (cur && cur->_left){cur = cur->_left;}_node = cur;}else{//如果右子树为空,且cur是parent的右子树,则先parent回溯至parent->_parent,再_node变为parent//如果右子树为空,且cur是parent的左子树,则_node变为parentnode* cur = _node;node* parent = cur->_parent;while (parent && cur == parent->_right){cur = parent;parent = parent->_parent;}_node = parent;}return *this;}iterator& operator--()   //和++反着来即可{if (_node->_left){node* cur = _node->_left;while (cur && cur->_right){cur = cur->_right;}_node = cur;}else{node* cur = _node;node* parent = cur->_parent;while (parent && cur == parent->_left){cur = parent;parent = parent->_parent;}_node = parent;}return *this;}bool operator!=(const iterator&s){return _node != s._node;}
};template<class K, class T,class keyoft>
class RBTtree
{
public:typedef treeiterator<T,T&,T*> iterator;typedef treeiterator<T, const T&, const T*> const_iterator;//指向的东西不能改变typedef RBTtreenode<T> node;iterator begin(){node* flag = root;while (flag&&flag->_left)//flag可能为nullptr{flag = flag->_left;}return iterator(flag);}iterator end(){return iterator(nullptr); //end用nullptr去构造!!!!!!!!}const_iterator begin() const{node* flag = root;while (flag && flag->_left)//flag可能为nullptr{flag = flag->_left;}return const_iterator(flag);}const_iterator end() const{return const_iterator(nullptr); //end用nullptr去构造!!!!!!!!}pair<node*, bool> insert(const T& _data)//!!!!!!!!!{if (root == nullptr){root = new node(_data);root->col = BLACK;//规定根必须是黑的return make_pair(root, true);}node* parent = nullptr; //比bst多了一个parentnode* cur = root;keyoft type;//取出data的K类型的数据while (cur){parent = cur;if (type(cur->data) < type(_data)) //这里取出key再进行比较{cur = cur->_right;}else if (type(cur->data) > type(_data)){cur = cur->_left;}else{return make_pair(cur,false);}}cur = new node(_data);cur->col = RED;//因为如果插入黑色的会使很多节点的一条路径上的黑色节点增多(相当于得罪了所有人),而插入红色则有可能只得罪父亲(如果父亲是红色的话)if (type(parent->data) < type(_data)){parent->_right = cur;}else{parent->_left = cur;}cur->_parent = parent;node* newnode = cur;//开始调整while (parent && parent->col == RED)//parent为黑不需要调整,如果cur变成root,parent就不存在退出循环{node* grandparent = parent->_parent;//祖父一定存在,因为只有根节点是没有祖父的,而根节点一定是黑色的if (parent == grandparent->_left){//      g//    p   unode* uncle = grandparent->_right;  //父亲在左则叔叔在右if (uncle && uncle->col == RED)     //情况一.如果叔叔存在且为红色{//变色parent->col = uncle->col = BLACK;grandparent->col = RED;//重置cur,parent,继续向上处理cur = grandparent;//变为祖父parent = cur->_parent;}else //叔叔不存在或为黑色,旋转加变色{//   g//  p// cif (cur == parent->_left)  //情况二.单旋{rotateR(grandparent);parent->col = BLACK;grandparent->col = RED;}//   g//  p//   celse      //情况三.cur==parent->_right,双旋{rotateL(parent);//经历一次左旋后变成情况二!!!!!!!!!!!(cur和parent换位置)rotateR(grandparent);cur->col = BLACK;grandparent->col = RED;}break;//调整一次就结束了,所以经历过旋转后不需要重置cur,parent,grandparent}}else{//      g//    u   p//node* uncle = grandparent->_left;  //父亲在右则叔叔在左if (uncle && uncle->col == RED){parent->col = uncle->col = BLACK;grandparent->col = RED;//cur = grandparent;parent = cur->_parent;}else{//    g//  u   p//        cif (cur == parent->_right){rotateL(grandparent);parent->col = BLACK;grandparent->col = RED;}else{//   g// u   p//    crotateR(parent);rotateL(grandparent);cur->col = BLACK;grandparent->col = RED;}break;//调整一次就结束了,所以经历过旋转后不需要重置cur,parent,grandparent}}}//1.如果parent和uncle都为RED,则可以一起变黑// 2.parent为黑不处理// 3.uncle为黑或不存在,parent为红,旋转+变色root->col = BLACK;//最后以防万一让根变为黑return make_pair(newnode, true);}void rotateL(node* parent)//左旋,(新节点插入到较高右子树的右侧)//   1.右右{node* subr = parent->_right;node* subrl = subr->_left;parent->_right = subrl;subr->_left = parent;node* ppnode = parent->_parent;parent->_parent = subr;if (subrl) //subrl可能为空!!!!!!!{subrl->_parent = parent;}if (parent == root) //即如果parent->_parent==nullptr{root = subr;subr->_parent = nullptr;}else{if (ppnode->_left == parent){ppnode->_left = subr;}else if (ppnode->_right == parent){ppnode->_right = subr;}subr->_parent = ppnode;}}void rotateR(node* parent)//右旋,(新节点插入到较高左子树的左侧)//   2.左左{node* subl = parent->_left;node* sublr = subl->_right;parent->_left = sublr;if (sublr)               //sublr可能为空!!!!!!!sublr->_parent = parent;node* ppnode = parent->_parent;subl->_right = parent;parent->_parent = subl;if (root == parent){root = subl;subl->_parent = nullptr;}else{if (ppnode->_left == parent){ppnode->_left = subl;}else if (ppnode->_right == parent){ppnode->_right = subl;}subl->_parent = ppnode;}}void inorder(){_inorder(root);}void _inorder(node* root){keyoft type;if (root == nullptr)return;_inorder(root->_left);cout << type(root->data)<< " ";_inorder(root->_right);}bool check(node* it, int blacknum, int flag){if (it == nullptr){if (blacknum == flag)return true;elsereturn false;}else if (it->col == RED && it->_parent->col == RED)//十分巧妙,因为孩子的情况有很多,但父亲不是红就是黑,所以判断父亲更合适return false;else if (it->col == BLACK)blacknum++;return check(it->_left, blacknum, flag) && check(it->_right, blacknum, flag);}bool isbalance(){return _isbalance(root);}bool _isbalance(node* root){if (root == nullptr)return true;else if (root->col == RED)return false;int blacknum = 0;int flag = 0;node* k = root;while (k){if (k->col == BLACK)flag++;k = k->_left;//这里十分巧妙,因为如果为红黑树,从某一节点到空的所有路径上的黑节点数量是一致的,所以可以先随便选一条路径,算出这一条路径上的黑节点数作为基准值,在由递归去和其他路径比较}return check(root, blacknum, flag);}private:node* root = nullptr;
};

myset.h

#include"rbt.h"
namespace zone
{template<class K>class set{public:struct setkeyoft //仿函数,用来取出红黑树节点data中的key{const K& operator()(const K& key){return key;}};//set这里的迭代器本质都是const_iterator,因为k要求无法修改typedef typename RBTtree<K, K, setkeyoft>::const_iterator iterator;//记得要使用typename告诉编译器RBTtree<K, K, setkeyoft>::iterator这个是类型,不是函数typedef typename RBTtree<K, K, setkeyoft>::const_iterator const_iterator;iterator begin()const{return it.begin();}iterator end()const{return it.end();}pair<iterator,bool> insert(const K& key){return it.insert(key);}void inorder(){it.inorder();}private:RBTtree<K,K,setkeyoft> it;};
}

mymap.h

#include"rbt.h"
namespace zone
{template<class K,class T>class map{public:struct setkeyoft{const K& operator()(const pair<K, T>& key){return key.first;}};//map这里的迭代器则使用的是iterator,因为k要求无法修改,但v可以修改,所以可以直接初始化时用pair<const K, T>typedef typename RBTtree<K, pair<const K, T>, setkeyoft>::iterator iterator;typedef typename RBTtree<K, pair<const K, T>, setkeyoft>::const_iterator const_iterator;pair<iterator, bool> insert(const pair<K, T>& key){return it.insert(key);}T& operator[](const K& key){pair<iterator, bool>ret = insert(make_pair(key,T()));//insert返回一个pair,first是iterator,second是bool类型return ret.first->second;}iterator begin(){return it.begin();}iterator end(){return it.end();}void inorder(){it.inorder();}private:RBTtree<K,pair<const K,T>, setkeyoft> it;};
}

test.cpp

#include<iostream>
#include<vector>
#include<string>using namespace std;#include"myset.h"
#include"mymap.h"void test1()
{zone::set<int> it;it.insert(1);it.insert(3);it.insert(5);it.insert(2);it.insert(4);zone::set<int>::iterator arr = it.begin();while (arr!=it.end() ){cout << *arr << " ";++arr;}//it.inorder();}void test2()
{zone::map<string,string> it;it.insert(make_pair("sort","排序"));it.insert(make_pair("right", "右"));it.insert(make_pair("left", "左"));it.insert(make_pair("middle", "中"));zone::map<string,string>::iterator arr = it.begin();while (arr != it.end()){arr->second += 'x';//map的v可修改cout << arr->first << " ";++arr;}//it.inorder();}void test3()
{string arr[] = { "香蕉","苹果","西瓜","苹果","苹果","西瓜","苹果"};zone::map<string, int> it;for (auto e : arr){it[e]++;}for (auto k : it){++k.second;cout << k.first << ":" << k.second << endl;}
}
int main()
{test3();return 0;
}

相关文章:

移情别恋c++ ദ്ദി˶ー̀֊ー́ ) ——13.mapset(模拟实现)

1.对红黑树进行改造 1.1treenode模板参数改变 之前构建treenode模板参数传的是class k,class v(set为k&#xff0c;k&#xff1b;map是k&#xff0c;v&#xff09;&#xff0c;现在直接用T代替 template<class T> //这里直接传了T作为模板参数&#xff0c;T可能是pai…...

【C++】多态(下)

个人主页~ 多态&#xff08;上&#xff09;~ 多态 四、多态的原理1、虚表的存储位置2、多态的原理3、动态绑定和静态绑定 五、单继承和多继承关系的虚函数表1、单继承中的虚函数表2、多继承中的虚函数表 六、多态中的一些小tips 四、多态的原理 1、虚表的存储位置 class A {…...

基于四种网络结构的WISDM数据集仿真及对比:Resnet、LSTM、Shufflenet及CNN

在上节中&#xff0c;我们已经详细介绍了WISDM数据集及如何使用CNN网络训练&#xff0c;得到了六个维度的模型仿真指标及五个维度的可视化分析&#xff0c;那么现在我们将训练模型推广到其他网路结构中去&#xff0c;通过仿真实验来对比一下不同网络之间对于WISDM数据集的训练效…...

【蚂蚁HR-注册/登录安全分析报告】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造成亏损无底洞…...

【分布式微服务云原生】详解Redis的主从模式,主服务器挂了如何从多个从服务器选出新的主服务器

深入探索Redis主从模式&#xff1a;架构、故障转移与最佳实践 摘要&#xff1a; 本文深入探讨了Redis的主从复制模式&#xff0c;包括其工作原理、故障转移机制以及如何配置和管理这一模式。文章通过清晰的结构和实例代码&#xff0c;帮助读者理解如何在实际项目中应用Redis主…...

Android Context是什么?有很多的context他们之间有什么区别?什么时候该使用哪个?

目录 一、Context是什么&#xff1f; 在Android中&#xff0c;Context是一个抽象类 &#xff0c;它代表了应用程序的当前状态&#xff0c;包括资源和类加载器等&#xff0c;它提供了一个应用运行所需的信息&#xff0c;比如我们要获取资源 &#xff0c;那么需要她&#xff0c;…...

数字解调同步技术

一些概念 载波同步 载波同步是一个过程&#xff0c;通过该过程&#xff0c;接收机使其本地载波振荡器的频率和相位与接收信号的频率和相位相适应。 载波相位同步 Carrier Phase Synchronization载波频率同步 Carrier Frequency Synchronization 帧同步 待更新 位同步 待…...

k8s搭建一主三从的mysql8集群---无坑

一&#xff0c;环境准备 1.1 k8s集群服务器 ip角色系统主机名cpumem192.168.40.129mastercentos7.9k8smaster48192.168.40.130node1centos7.9k8snode148192.168.40.131node2centos7.9k8snode248192.168.40.132node3centos7.9k8snode348 k8s集群操作请参考《K8s安装部署&…...

Oracle架构之物理存储中各种文件详解

文章目录 1 物理存储1.1 简介1.2 数据文件&#xff08;data files&#xff09;1.2.1 定义1.2.2 分类1.2.2.1 系统数据文件1.2.2.2 撤销数据文件1.2.2.3 用户数据文件1.2.2.4 临时数据文件 1.3 控制文件&#xff08;Control files&#xff09;1.3.1 定义1.3.2 查看控制文件1.3.3…...

AR 领域的突破——微型化显示屏为主流 AR 眼镜铺平道路

概述 多年来&#xff0c;增强现实 (AR) 技术一直吸引着人们的想象力&#xff0c;有望将数字信息与我们的物理世界无缝融合。通过将计算机生成的图像叠加到现实世界的视图上&#xff0c;AR 有可能彻底改变我们与环境的互动方式。从增强游戏体验到协助手术室的外科医生&#xff…...

Web安全 - 构建全面的业务安全保护防御体系

文章目录 业务安全概述业务安全 vs. 基础安全业务安全的防护业务安全的防护策略1. 用户资源对抗的技术实现与优化2. IP资源对抗的技术实现与优化3. 设备资源对抗的技术实现与优化4. 操作资源对抗的技术实现与优化实际应用场景中的策略 典型场景业务场景 1&#xff1a;新用户注册…...

机器学习(2):机器学习的相关术语

场景示例&#xff1a; 你周日约了小李、老王打牌&#xff0c;小李先来了&#xff0c;老王没来。你想打电话叫老王过来。小李说&#xff1a;“你别打电话啦&#xff0c;昨天老王喜欢的球队皇马输球了&#xff0c;他的项目在上个礼拜也没成功上线&#xff0c;再加上他儿子期末考…...

Leecode热题100-75.颜色分类

给定一个包含红色、白色和蓝色、共 n 个元素的数组 nums &#xff0c;原地 对它们进行排序&#xff0c;使得相同颜色的元素相邻&#xff0c;并按照红色、白色、蓝色顺序排列。 我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。 必须在不使用库内置的 sort 函数的情况下解…...

408算法题leetcode--第22天

200. 岛屿数量 200. 岛屿数量时间&#xff1a;O(mn)&#xff1b;空间&#xff1a;O(min(m, n))&#xff0c;队列最大入队个数&#xff0c;可以想象从左上到右下&#xff0c;第一次入队1个&#xff0c;第二次出队1&#xff0c;入队2&#xff0c;第三次出队2&#xff0c;入队3……...

dubbo微服务

一.启动nacos和redis 1.虚拟机查看是否开启nacos和redis docker ps2.查看是否安装nacos和redis docker ps -a3.启动nacos和redis docker start nacos docker start redis-6379 docker ps二.创建三个idea的maven项目 1.第一个项目dubboapidemo 2.1.1向pom.xml里添加依赖 …...

如何在 DAX 中计算多个周期的移动平均线

在 DAX 中计算移动聚合很容易。但是&#xff0c;计算一段时间内的移动平均值时会有一些陷阱。由于其中一些陷阱是定义问题&#xff0c;因此我们必须小心&#xff0c;不要选择错误的方法。让我们看看细节。欢迎来到雲闪世界。 添加图片注释&#xff0c;不超过 140 字&#xff08…...

微信小程序 图片的上传

错误示范 /*从相册中选择文件 微信小程序*/chooseImage(){wx.chooseMedia({count: 9,mediaType: [image],sourceType: [album],success(res) {wx.request({url:"发送的端口占位符",data:res.tempFiles[0].tempFilePath,method:POST,success(res){//请求成功后应该返…...

软件测试人员发现更多程序bug

软件测试人员发现更多程序bug 1. 理解需求和业务&#xff0c;需求评审时候发现bug 熟悉了产品的业务流程、才能迅速找出软件中存在的一些重要的缺陷&#xff0c;发现的软件缺陷才是有价值的。否则即使你能找到一些软件缺陷&#xff0c;那也是纯软件的缺陷&#xff0c;价值不大…...

Nagle 算法:优化 TCP 网络中小数据包的传输

1. 前言 在网络通信中&#xff0c;TCP&#xff08;传输控制协议&#xff09;是最常用的协议之一&#xff0c;广泛应用于各种网络应用&#xff0c;如网页浏览、文件传输和在线游戏等。然而&#xff0c;随着互联网的普及&#xff0c;小数据包的频繁传输成为一个不容忽视的问题。…...

C#入门教程

目录 1.if分支语句 2.面向对象 3.static简单说明 1.if分支语句 我们的这个C#里面的if语句以及这个if-else语句和C语言里面没有区别&#xff0c;就是打这个输出上面的方式不一样&#xff0c;c#里面使用的是这个console.writeline这个指令&#xff0c;其他的这个判断逻辑都是一…...

【kafka】Golang实现分布式Masscan任务调度系统

要求&#xff1a; 输出两个程序&#xff0c;一个命令行程序&#xff08;命令行参数用flag&#xff09;和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽&#xff0c;然后将消息推送到kafka里面。 服务端程序&#xff1a; 从kafka消费者接收…...

Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)

目录 1.TCP的连接管理机制&#xff08;1&#xff09;三次握手①握手过程②对握手过程的理解 &#xff08;2&#xff09;四次挥手&#xff08;3&#xff09;握手和挥手的触发&#xff08;4&#xff09;状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...

电脑插入多块移动硬盘后经常出现卡顿和蓝屏

当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时&#xff0c;可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案&#xff1a; 1. 检查电源供电问题 问题原因&#xff1a;多块移动硬盘同时运行可能导致USB接口供电不足&#x…...

什么是EULA和DPA

文章目录 EULA&#xff08;End User License Agreement&#xff09;DPA&#xff08;Data Protection Agreement&#xff09;一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA&#xff08;End User License Agreement&#xff09; 定义&#xff1a; EULA即…...

c#开发AI模型对话

AI模型 前面已经介绍了一般AI模型本地部署&#xff0c;直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型&#xff0c;但是目前国内可能使用不多&#xff0c;至少实践例子很少看见。开发训练模型就不介绍了&am…...

汇编常见指令

汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX&#xff08;不访问内存&#xff09;XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...

基于matlab策略迭代和值迭代法的动态规划

经典的基于策略迭代和值迭代法的动态规划matlab代码&#xff0c;实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...

AGain DB和倍数增益的关系

我在设置一款索尼CMOS芯片时&#xff0c;Again增益0db变化为6DB&#xff0c;画面的变化只有2倍DN的增益&#xff0c;比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析&#xff1a; 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

如何更改默认 Crontab 编辑器 ?

在 Linux 领域中&#xff0c;crontab 是您可能经常遇到的一个术语。这个实用程序在类 unix 操作系统上可用&#xff0c;用于调度在预定义时间和间隔自动执行的任务。这对管理员和高级用户非常有益&#xff0c;允许他们自动执行各种系统任务。 编辑 Crontab 文件通常使用文本编…...