[C++随想录] map和set的封装

map和set的封装

  • 1. 红黑树模版的改变
    • 1.1 RBTree类模板 头的改变
    • 1.2 封装迭代器类
      • 1.2.1 构造 && 拷贝构造
      • 1.2.2. ++
      • 1.2.3. - -
      • 1.2.4. 其他运算符重载
    • 1.3 RBTree类实现普通迭代器和const迭代器
  • 2. set的底层逻辑
  • 3. map的底层逻辑
  • 4. 源码
    • 4.1 RBTree类
    • 4.2 set类
    • 4.3 map类

1. 红黑树模版的改变

1.1 RBTree类模板 头的改变

原来的红黑树模版是 <class K, class V>
由于 set 的存储数据是K类型, 而map的存储数据是 <K, V>类型
⇒ 红黑树的模版要进行改变


🗨️ set中控制 key不允许修改为什么不用 RBTree<K, const K, SetofT>?

  • 见set中 普通迭代器 和 const迭代器的实现

1.2 封装迭代器类

1.2.1 构造 && 拷贝构造

  1. 构造
_iterator(Node* t)
	:_node(t)
{}
  1. 用普通迭代器初始化const迭代器
// 用普通迭代器去初始化const迭代器
_iterator(const Iterator& it)
	:_node(it._node)
{}

🗨️为什么要写 用普通迭代器初始化const迭代器呢 ?

  • 见set的 insert逻辑
    按照道理来说, 迭代器是 内置类型 ⇒ 浅拷贝, 是不需要我们亲自写拷贝构造的

1.2.2. ++

++ — — 返回 中序 中的下一个节点
由于 中序是 左跟右 ⇒ 当前节点 ++ 主要有两大情况 右子树为空, 右子树不为空

  1. 右子树为空, 说明当前根节点的右子树的逻辑并没有结束, 意味着要找到右子树的最小节点
  2. 右子树为空, 说明当前根节点的整个逻辑已经结束(左子树向上, 向根节点返回左子树的情况), 意味着要找到最近的孩子是父亲左孩子的父亲节点
self& operator++()
{
	// 右子树不为空
	if (_node->_right)
	{
		Node* rightmin = _node->_right;
		while (rightmin->_left)
		{
			rightmin = rightmin->_left;
		}
		_node = rightmin;
	}
	// 右子树为空
	// 向上回溯并返回最近的孩子是父亲左孩子的父亲节点
	else
	{
		Node* cur = _node;
		Node* parent = cur->_parent;
		while (parent && cur == parent->_right)
		{
			cur = parent;
			parent = parent->_parent;
		}
		_node = parent;
	}

	return *this;
}

1.2.3. - -

减减 — — 加加反过来, 右跟左
当前节点减减, 主要有两大情况 左子树为空, 左子树不问空

  1. 左子树不为空, 说明当前根结点的左子树逻辑并没有结束, 意味着要找到左子树中的最大节点
  2. 左子树为空, 说明当前根节点的这个逻辑已经结束(右子树向上, 向根节点返回右子树的情况), 意味着要找到最近的 孩子是父亲右孩子的父亲节点
self& operator--()
{
	// 左子树不为空
	if (_node->_left)
	{
		Node* leftmost = _node->_left;
		while (leftmost->_right)
		{
			leftmost = leftmost->_right;
		}
		_node = leftmost;
	}
	// 左子树为空
	// 找到最近的孩子是父亲右孩子的父亲节点
	else
	{
		Node* cur = _node;
		Node* parent = cur->_parent;
		while (parent && parent->_left == cur)
		{
			cur = parent;
			parent = parent->_parent;
		}
		_node = parent;
	}

	return *this;
}

1.2.4. 其他运算符重载

  1. operator!=
bool operator !=(const self& t)
{
	return _node != t._node;
}
  1. operator==
bool operator ==(const self& t)
{
	return _node->_data == t._node;
}
  1. operator*
Ptr operator*()
{
	return _node->_data;
}
  1. operator->
Ref operator->()
{
	return &_node->_data;
}

1.3 RBTree类实现普通迭代器和const迭代器

  1. 类型
typedef _iterator<T, T&, T*> iterator;
typedef _iterator<T, const T&, const T*> const_iterator;
  1. begin, end
// begin - 最左节点
iterator begin()
{
	Node* leftmin = _root;
	while (leftmin && leftmin->_left)
	{
		leftmin = leftmin->_left;
	}
	
	// return iterator(leftmin);
	return leftmin;
}

iterator end()
{
	return iterator(nullptr);
}

const_iterator begin()const
{
	Node* leftmin = _root;
	while (leftmin && leftmin->_left)
	{
		leftmin = leftmin->_left;
	}
	
	// return const_iterator(leftmin);
	return leftmin;
}

const_iterator end()const
{
	return const_iterator(nullptr);
}

2. set的底层逻辑

  1. SetofT
  • 底层RBTree类中, 只知道数据类型是 T, 而不知道 set 和 map的具体数据类型 && set的数据类型是 K, 而map的数据类型是pair<K, V>⇒ 这个模版T实现了 泛型编程
    但是有一点是相同的, 都需要 数据中的 key 来进行比较逻辑 ⇒ 我们需要一个函数来 提取数据中的key

set中数据类型是K, key的类型也是 K ⇒ 我们 直接返回

struct SetofT
{
	const K& operator()(const K& data)
	{
		return data;
	}
};
  1. 迭代器
typedef typename RBTree<K, K, SetofT>::const_iterator iterator;
typedef typename RBTree<K, K, SetofT>::const_iterator const_iterator;

我们发现 : set中 迭代器 和 const迭代器都是 const迭代器保证了 key是不能进行修改的
🗨️ set中控制 key不允许修改为什么不用 RBTree<K, const K, SetofT>?

  • 如果数据类型直接传 const类型 ⇒ 常量常量, 结构是不成立的
  1. begin, end
    一个const版本即可
iterator begin()const
{
	return _t.begin();
}

iterator end()const
{
	return _t.end();
}
  1. find
iterator find(const K& key)
{
	return _t.find(key);
}
  1. insert
pair<iterator, bool>& insert(const K& data)
{
	pair<RBTree<K, K, SetofT>::iterator, bool> tem = _t.Insert(data);
	pair<iterator, bool> res = tem;
	return res;
}
  • 返回值是 pair结构的原因:
    map的 [ ] 的本质是调用 insert, 有如下功能: (以 map[ret] 为例子)
    1. ret 在map中存在, 返回value
    2. ret 在map中不存在, 则新插入该节点

⇒ 这就要求insert 返回的是一个 pair结构, <节点迭代器, 是否存在> ⇒ pair<iterator, bool>
由于 set 和 map 共用同一个 红黑树 ⇒ set中的 insert的返回值也是一个 pair结构

  • 进行类型转换的原因
    注意: set中的iterator是 const_iterat
    而RBTree中 Insert的返回值是 pair<iterator, bool> && RBTre类中的 iterator是正常的, 是普通迭代器
    ⇒ 就会出现 pair<const_iterator, bool> = pair<iterator, bool> 的类型不匹配问题
    由于 普通迭代器是可以初始化const迭代器的 (在RBTree类中的 迭代器类中要多一个 用普通迭代器去初始化const迭代器的函数 ) ⇒ 所以, 我们要先接收一下 Insert的返回值, 然后再进行类型转换

3. map的底层逻辑

  1. MapofT
struct MapofT
{
	const K& operator()(const pair<K, V>& data)
	{
		return data.first;
	}
};
  1. 迭代器
typedef typename RBTree<K, pair<const K, V>, MapofT>::iterator iterator;
typedef typename RBTree<K, pair<const K, V>, MapofT>::const_iterator const_iterator;
  1. begin, end
iterator begin()
{
	return _t.begin();
}

iterator end()
{
	return _t.end();
}

const_iterator begin()const
{
	return _t.begin();
}

const_iterator end()const
{
	return _t.end();
}
  1. find
iterator find(const K& key)
{
	return _t.find(key);
}
  1. insert
pair<iterator, bool> insert(const pair<K, V>& data)
{
	return _t.Insert(data);
}
  1. operator[ ]
V& operator[](const K& key)
{
	pair<iterator, bool> ret = insert(make_pair(key, V()));
	return ret.first->second;
}

4. 源码

4.1 RBTree类

#pragma once

#include<iostream>
#include<assert.h>

using namespace std;

	// 枚举
	enum Color
	{
		RED,
		BLACK 
	};

	template<class T>
	struct RBTreeNode
	{
	public:
		RBTreeNode(const T& data)
			:_data(data)
		{}

	public:
		T _data;
		Color _color = BLACK;
		RBTreeNode<T>* _left = nullptr;
		RBTreeNode<T>* _right = nullptr;
		RBTreeNode<T>* _parent = nullptr;
	};

	template<class T, class Ptr, class Ref>
	struct _iterator
	{
		typedef RBTreeNode<T> Node;
		typedef _iterator<T, Ptr, Ref> self;
		typedef _iterator<T, T&, T*> Iterator;

	public:

		// 用普通迭代器去初始化const迭代器
		_iterator(const Iterator& it)
			:_node(it._node)
		{}

		_iterator(Node* t)
			:_node(t)
		{}

		bool operator !=(const self& t)
		{
			return _node != t._node;
		}
		bool operator ==(const self& t)
		{
			return _node->_data == t._node;
		}

		Ptr operator*()
		{
			return _node->_data;
		}

		Ref operator->()
		{
			return &_node->_data;
		}

		self& operator++()
		{
			if (_node->_right)
			{
				Node* rightmin = _node->_right;
				while (rightmin->_left)
				{
					rightmin = rightmin->_left;
				}
				_node = rightmin;
			}
			else
			{
				Node* cur = _node;
				Node* parent = cur->_parent;
				while (parent && cur == parent->_right)
				{
					cur = parent;
					parent = parent->_parent;
				}
				_node = parent;
			}

			return *this;
		}

		self& operator--()
		{
			if (_node->_left)
			{
				Node* leftmost = _node->_left;
				while (leftmost->_right)
				{
					leftmost = leftmost->_right;
				}
				_node = leftmost;
			}
			else
			{
				Node* cur = _node;
				Node* parent = cur->_parent;
				while (parent && parent->_left == cur)
				{
					cur = parent;
					parent = parent->_parent;
				}
				_node = parent;
			}

			return *this;
		}

	public:
		Node* _node;

	};

	template<class K, class T, class KeyofT>
	struct RBTree
	{
		typedef RBTreeNode<T> Node;
	public:

		typedef _iterator<T, T&, T*> iterator;
		typedef _iterator<T, const T&, const T*> const_iterator;

	public:

		iterator begin()
		{
			Node* leftmin = _root;
			while (leftmin && leftmin->_left)
			{
				leftmin = leftmin->_left;
			}

			return leftmin;
		}

		iterator end()
		{
			return iterator(nullptr);
		}

		const_iterator begin()const
		{
			Node* leftmin = _root;
			while (leftmin && leftmin->_left)
			{
				leftmin = leftmin->_left;
			}

			return leftmin;
		}

		const_iterator end()const
		{
			return const_iterator(nullptr);
		}

		Node* find(const K& key)
		{
			KeyofT kot;

			Node* cur = _root;
			while (cur)
			{
				if (key > kot(cur->_data))
				{
					cur = cur->_right;
				}
				else if (key < kot(cur->_data))
				{
					cur = cur->_left;
				}
				else
				{
					return cur;
				}
			}

			return nullptr;
		}

		void RotateL(Node* parent)
		{
			++RotateCount;

			Node* cur = parent->_right;
			Node* grandfather = parent->_parent;
			Node* curleft = cur->_left;

			// 旋转核心
			parent->_right = curleft;
			cur->_left = parent;

			// 更新父亲
			// 1. parent && curleft
			if (curleft)
			{
				curleft->_parent = parent;
			}
			parent->_parent = cur;

			// 2.更新cur
			if (grandfather == nullptr)
			{
				cur->_parent = nullptr;
				_root = cur;
			}
			else
			{
				if (grandfather->_left == parent)
				{
					grandfather->_left = cur;
				}
				else
				{
					grandfather->_right = cur;
				}

				cur->_parent = grandfather;
			}

		}

		void RotateR(Node* parent)
		{
			++RotateCount;

			Node* cur = parent->_left;
			Node* grandfather = parent->_parent;
			Node* curright = cur->_right;

			// 旋转核心
			parent->_left = curright;
			cur->_right = parent;

			// 更新链接关系
			// 1. parent && curright
			if (curright)
			{
				curright->_parent = parent;
			}
			parent->_parent = cur;

			// 2.更新cur
			if (grandfather == nullptr)
			{
				cur->_parent = nullptr;
				_root = cur;
			}
			else
			{
				if (grandfather->_left == parent)
				{
					grandfather->_left = cur;
				}
				else
				{
					grandfather->_right = cur;
				}

				cur->_parent = grandfather;
			}
		}

		pair<iterator, bool> Insert(const T& data)
		{
			KeyofT kot;
			if (_root == nullptr)
			{
				// 根节点是黑色的
				_root = new Node(data);
				_root->_color = BLACK;
				return make_pair(iterator(_root), true);
			}

			Node* parent = _root;
			Node* cur = _root;
			while (cur)
			{
				if (kot(data) > kot(cur->_data))
				{
					parent = cur;
					cur = cur->_right;
				}
				else if (kot(data) < kot(cur->_data))
				{
					parent = cur;
					cur = cur->_left;
				}
				else
				{
					return make_pair(iterator(cur), false);
				}
			}

			// 新建一个节点, 默认是红色
			cur = new Node(data);
			cur->_color = RED;

			// 链接cur 和 parent
			if (kot(cur->_data) > kot(parent->_data))
			{
				parent->_right = cur;
			}
			else
			{
				parent->_left = cur;
			}
			cur->_parent = parent;

			// 更改黑红比例
			while (parent && parent->_color == RED)
			{
				Node* grandfather = parent->_parent;

				if (grandfather->_left == parent)
				{
					Node* uncle = grandfather->_right;

					// u存在且为红
					if (uncle && uncle->_color == RED)
					{
						// 颜色变化
						grandfather->_color = RED;
						parent->_color = uncle->_color = BLACK;

						// 继续向上调整
						cur = grandfather;
						parent = cur->_parent;
					}
					else // u不存在 或 u存在且为黑色
					{
						if (cur == parent->_left)
						{
							RotateR(grandfather);

							grandfather->_color = RED;
							parent->_color = BLACK;
						}
						else
						{
							RotateL(parent);
							RotateR(grandfather);

							cur->_color = BLACK;
							grandfather->_color = RED;
						}

						break;
					}
				}
				else if (grandfather->_right == parent)
				{
					Node* uncle = grandfather->_left;

					// u存在且为红
					if (uncle && uncle->_color == RED)
					{
						// 颜色变化
						grandfather->_color = RED;
						uncle->_color = parent->_color = BLACK;

						// 继续向上调整
						cur = grandfather;
						parent = cur->_parent;
					}
					// u不存在 或 u存在且为黑色
					else
					{
						if (parent->_right == cur)
						{
							RotateL(grandfather);

							parent->_color = BLACK;
							grandfather->_color = RED;
						}
						else
						{
							RotateR(parent);
							RotateL(grandfather);

							cur->_color = BLACK;
							grandfather->_color = RED;
						}

						break;
					}
				}
				else
				{
					assert("黑红比例失控!");
				}
			}

			// 暴力统一处理根节点的颜色
			_root->_color = BLACK;

			return make_pair(iterator(cur), true);
		}

		int Height()
		{
			return Height(_root);
		}

		int Height(Node* root)
		{
			if (root == nullptr)
				return 0;

			int left = Height(root->_left);
			int right = Height(root->_right);

			return left > right ? left + 1 : right + 1;
		}

		bool CheckColour(Node* root, int blacknum, int benchmark)
		{
			if (root == nullptr)
			{
				if (blacknum != benchmark)
					return false;

				return true;
			}

			if (root->_color == BLACK)
			{
				++blacknum;
			}

			if (root->_color == RED && root->_parent && root->_parent->_color == RED)
			{
				cout << root->_kv.first << "出现连续红色节点" << endl;
				return false;
			}

			return CheckColour(root->_left, blacknum, benchmark)
				&& CheckColour(root->_right, blacknum, benchmark);
		}

		bool IsBalance()
		{
			return IsBalance(_root);
		}

		bool IsBalance(Node* root)
		{
			if (root == nullptr)
				return true;

			if (root->_color != BLACK)
			{
				return false;
			}

			// 基准值
			int benchmark = 0;
			Node* cur = _root;
			while (cur)
			{
				if (cur->_color == BLACK)
					++benchmark;

				cur = cur->_left;
			}

			return CheckColour(root, 0, benchmark);
		}

		int GetRoateCount()
		{
			return RotateCount;
		}

	private:
		Node* _root = nullptr;
		int RotateCount = 0;
	};

4.2 set类

#pragma once

#include"RBTree.h"

namespace muyu
{

	template<class K>
	class set
	{
		struct SetofT
		{
			const K& operator()(const K& data)
			{
				return data;
			}
		};

	public:
		typedef typename RBTree<K, K, SetofT>::const_iterator iterator;
		typedef typename RBTree<K, K, SetofT>::const_iterator const_iterator;


	public:
		pair<iterator, bool>& insert(const K& data)
		{
			pair<RBTree<K, K, SetofT>::iterator, bool> tem = _t.Insert(data);
			pair<iterator, bool> res = tem;
			return res;
		}

		iterator begin()const
		{
			return _t.begin();
		}

		iterator end()const
		{
			return _t.end();
		}

		iterator find(const K& key)
		{
			return _t.find(key);
		}

	private:
		RBTree<K, K, SetofT> _t;
	};
}

4.3 map类

#pragma once

#include"RBTree.h"

namespace muyu
{

	template<class K, class V>
	class map
	{
		struct MapofT
		{
			const K& operator()(const pair<K, V>& data)
			{
				return data.first;
			}
		};
	public:
		typedef typename RBTree<K, pair<const K, V>, MapofT>::iterator iterator;
		typedef typename RBTree<K, pair<const K, V>, MapofT>::const_iterator const_iterator;


	public:
		pair<iterator, bool> insert(const pair<K, V>& data)
		{
			return _t.Insert(data);
		}

		iterator begin()
		{
			return _t.begin();
		}

		iterator end()
		{
			return _t.end();
		}

		const_iterator begin()const
		{
			return _t.begin();
		}
		
		iterator find(const K& key)
		{
			return _t.find(key);
		}
		
		const_iterator end()const
		{
			return _t.end();
		}

		V& operator[](const K& key)
		{
			pair<iterator, bool> ret = insert(make_pair(key, V()));
			return ret.first->second;
		}

	private:
		RBTree<K, pair<const K, V>, MapofT> _t;
	};
}

遥望中原,荒烟外、许多城郭。
想当年、花遮柳护,凤楼龙阁。
万岁山前珠翠绕,蓬壶殿里笙歌作。
到而今、铁骑满郊畿,风尘恶。
兵安在?膏锋锷。
民安在?填沟壑。
叹江山如故,千村寥落。
何日请缨提锐旅,一鞭直渡清河洛。
却归来、再续汉阳游,骑黄鹤。
— — 岳飞《满江红·登黄鹤楼有感》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/135102.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

搭建Docker

一、概念 云服务器大家肯定不陌生了&#xff0c;相比较传统物理服务器来说他的价格&#xff0c;个性化的配置服务&#xff0c;节省了很多的运维成本&#xff0c;越来越多的企业以及个人开发者更加的青睐于云服务器。有了属于自己的服务器就可以部署搭建自己个人网站了&#xf…

js动态显示当前时间

目录 1、封装时间函数 2、在页面写一个div标签&#xff0c;用来存放时间 3、获取div标签&#xff0c;开启定时器&#xff0c;时间为1000ms 4、先调用时间函数&#xff0c;防止页面加载延迟&#xff0c;再在定时器里调用 完整代码 效果图 1、封装时间函数 function getTi…

asp.net 在线音乐网站系统VS开发sqlserver数据库web结构c#编程Microsoft Visual Studio

一、源码特点 asp.net 在线音乐网站系统是一套完善的web设计管理系统&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为vs2010&#xff0c;数据库为sqlserver2008&#xff0c;使用c#语言 开发 asp.net 在线音乐网站系统1 应用…

Least Square Method 最小二乘法(图文详解,必懂)

最小二乘法是一种求解线性回归模型的优化方法&#xff0c;其目标是最小化数据点和拟合直线之间的残差平方和。这意味着最小二乘法关注的是找到一个直线&#xff0c;使得所有数据点与该直线的偏差的平方和最小。在数学公式中&#xff0c;如果y是实际值&#xff0c;y是函数估计值…

计算机组成原理第四章(存储系统)(一)

一、存储器概述 1.分类&#xff1a; 存取方式&#xff1a;随机存储器&#xff08;RAM&#xff09;、顺序存储器&#xff08;SAM&#xff09;、直接存储器&#xff08;DAM&#xff09; 存储介质&#xff1a;磁性材料存储器、半导体存储器、光存储器 功能和存取速度&#xff1a; …

【阿里云】函数计算 X 通义千问快速部署

写在前面&#xff1a;博主是一只经过实战开发历练后投身培训事业的“小山猪”&#xff0c;昵称取自动画片《狮子王》中的“彭彭”&#xff0c;总是以乐观、积极的心态对待周边的事物。本人的技术路线从Java全栈工程师一路奔向大数据开发、数据挖掘领域&#xff0c;如今终有小成…

2023年施工升降机司机(建筑特殊工种)证模拟考试题库及施工升降机司机(建筑特殊工种)理论考试试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2023年施工升降机司机(建筑特殊工种)证模拟考试题库及施工升降机司机(建筑特殊工种)理论考试试题是由安全生产模拟考试一点通提供&#xff0c;施工升降机司机(建筑特殊工种)证模拟考试题库是根据施工升降机司机(建筑特…

论文笔记--Baichuan 2: Open Large-scale Language Models

论文笔记--Baichuan 2: Open Large-scale Language Models 1. 文章简介2. 文章概括3 文章重点技术3.1 预训练3.1.1 预训练数据3.1.2 模型架构 3.2 对齐3.2.1 SFT3.2.2 Reward Model(RM)3.2.3 PPO 3.3 安全性 4. 文章亮点5. 原文传送门 1. 文章简介 标题&#xff1a;Baichuan 2…

IP-guard Webserver view 远程命令执行漏洞【2023最新漏洞】

IP-guard Webserver view 远程命令执行漏洞【2023最新漏洞】 一、漏洞描述二、漏洞影响三、漏洞危害四、FOFA语句五、漏洞复现1、手动复现yaml pocburp发包 2、自动化复现小龙POC检测工具下载地址 免责声明&#xff1a;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传…

【小沐学写作】PPT、PDF文件添加水印(Python)

文章目录 1、简介2、ppt添加水印2.1 PowerPoint幻灯片母版2.2 iSlide插件&#xff08;收费&#xff09;2.2.1 iSlide简介2.2.2 iSlide定价2.2.3 iSlide水印 2.3 Python代码2.3.1 Aspose.Slides for Python&#xff08;收费&#xff09; 3、pdf添加水印3.1 Python代码3.1.1 PyPD…

头歌答案--数据持久化(非数据库)

目录 ​编辑 数据持久化&#xff08;非数据库&#xff09; 第1关&#xff1a;数据持久化&#xff08;非数据库&#xff09; 任务描述 多线程、多进程爬虫 第1关&#xff1a;多线程、多进程爬虫 任务描述 Scrapy爬虫基础 任务描述 MySQL数据库编程 第1关&#xff1a;…

【视觉SLAM十四讲学习笔记】第二讲——初识SLAM

专栏系列文章如下&#xff1a; 【视觉SLAM十四讲学习笔记】第一讲 一个机器人&#xff0c;如果想要探索某一块区域&#xff0c;它至少需要知道两件事&#xff1a; 我在什么地方——定位周围环境是什么样——建图 一方面需要明白自身的状态&#xff08;即位置&#xff09;&#…

八种架构设计模式优缺点

目录 1、软件架构 2、架构设计模式 2.1、单库单应用模式 2.2、内容分发模式 2.3、查询分离模式 2.4 微服务模式 2.5 多级缓存模式 1、软件架构 软件架构是指对软件系统整个结构和组成部分之间的关系进行抽象和定义的过程&#xff0c;旨在解决系统设计和实现过程中的复杂…

2023年【汽车驾驶员(高级)】找解析及汽车驾驶员(高级)复审考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 汽车驾驶员&#xff08;高级&#xff09;找解析是安全生产模拟考试一点通总题库中生成的一套汽车驾驶员&#xff08;高级&#xff09;复审考试&#xff0c;安全生产模拟考试一点通上汽车驾驶员&#xff08;高级&#…

作业类型7333RG没有为成本中心7333+7000501在年度2023

创建 作业类型KP26 更改成本中心为生产部。 查看作业类型KL02, 可以看到这个有效期已超期&#xff0c;重新创建有效期KL01 但是创建成本要素时报错&#xff0c; 用KA06创建成本要素 返回KL01更正成本要素 这个有效期要注意不要重叠&#xff0c;否则无法创建新的有效期

【博士每天一篇文献-模型】A mechanistic model of connector hubs, modularity and cognition

阅读时间&#xff1a;2023-11-10 1 介绍 年份&#xff1a;2018 作者&#xff1a;Maxwell A. Bertolero, B. T. Thomas Yeo 期刊&#xff1a; nature human behaviour 引用量&#xff1a;180 2 创新点 作者提出了一个机制模型&#xff0c;解释了连接中枢的功能以及其对认知表…

Linux内核有什么之内存管理子系统有什么第七回 —— 小内存分配(5)

接前一篇文章&#xff1a;Linux内核有什么之内存管理子系统有什么第六回 —— 小内存分配&#xff08;4&#xff09; 本文内容参考&#xff1a; linux进程虚拟地址空间 《趣谈Linux操作系统 核心原理篇&#xff1a;第四部分 内存管理—— 刘超》 4.6 深入理解 Linux 虚拟内存…

手把手带你创建一个自己的GPTs

大家好&#xff0c;我是五竹。 最近GPT又进行了大升级&#xff0c;这一下又甩了国内AI几条街&#xff0c;具体更新了哪些内容之前的一篇文章中其实已经说过了&#xff1a;ChatGPT 王炸升级&#xff01;更强版 GPT-4 上线&#xff01; 其中最重要的一点就是支持自定义GPT&…

【博士每天一篇文献-算法】A pseudo-inverse decomposition-based self-organizing modular echo

阅读时间&#xff1a;2023-11-6 1 介绍 年份&#xff1a;2022 作者&#xff1a;王雷&#xff0c;北京信息科技大学自动化学院 期刊&#xff1a; Applied Soft Computing 引用量&#xff1a;12 提出了一种基于伪逆分解的自组织模块化回声状态&#xff08;PDSM-ESN&#xff09…

代码随想录算法训练营第四十九天丨 动态规划part12

309.最佳买卖股票时机含冷冻期 思路 相对于动态规划&#xff1a;122.买卖股票的最佳时机II (opens new window)&#xff0c;本题加上了一个冷冻期 在动态规划&#xff1a;122.买卖股票的最佳时机II (opens new window)中有两个状态&#xff0c;持有股票后的最多现金&#xf…