【C++】几个基本容器的模拟实现(string,vector,list,stack,queue,priority_queue)

目录

一.string

二.vector

三.list

四.stack

五.queue

六.priority_queue


一.string

#pragma once

namespace hebre
{
	class string
	{
	public:
		typedef char* iterator;
		typedef const char* const_iterator;
		//Member functions
		string()
			:_str(new char[1]{'\0'})
			,_size(0)
			,_capacity(0)
		{}
		string(const string& str)
		{
			_size = str._size;
			_capacity = str._capacity;
			_str = new char[_size + 1];
			strcpy(_str, str._str);
		}
		string(const string& str, size_t pos, size_t len = npos)
		{
			if (len > _size - pos)
			{
				len = _size - pos;
			}
			_str = new char[len + 1];
			_capacity = _size = len;
			size_t i = 0;
			size_t n = len;
			while (n--)
			{
				_str[i] = str._str[pos];
				i++;
				pos++;
			}
			_str[len] = '\0';
		}
		string(const char* s)
		{
			_size = strlen(s);
			_capacity = _size;
			_str = new char[_size + 1];
			strcpy(_str, s);
		}
		string(const char* s, size_t n)
		{
			_size = n;
			_capacity = n;
			_str = new char[n + 1];
			size_t i = 0;
			while (i < n)
			{
				_str[i] = s[i];
				i++;
			}
			_str[_size] = '\0';
		}
		string(size_t n, char c)
		{
			_size = n;
			_capacity = n;
			_str = new char[n + 1];
			size_t i = 0;
			while (i < n)
			{
				_str[i] = c;
			}
			_str[_size] = '\0';
		}
		template<class InputIterator>
		string(InputIterator first, InputIterator last)
		{
			while (first != last)
			{
				push_back(*first);
				first++;
			}
		}
		~string()
		{
			delete[] _str;
			_str = nullptr;
			_size = 0;
			_capacity = 0;
		}
		string& operator= (const char* s)
		{
			string tmp(s);
			swap(tmp);
			return *this;
		}
		string& operator=(string s)
		{
			swap(s);
			return *this;
		}
		//Iterators
		iterator begin()
		{
			return _str;
		}
		const_iterator begin() const
		{
			return _str;
		}
		iterator end()
		{
			return _str + _size;
		}
		const_iterator end() const
		{
			return _str + _size;
		}
		//Capacity
		size_t size() const
		{
			return _size;
		}
		void resize(size_t n, char c = '\0')
		{
			if (n <= _size)
			{
				_str[n - 1] = '\0';
				_size = n;
			}
			else
			{
				if (n > _capacity)
				{
					reserve(n);
				}
				for (size_t i = _size; i < n; i++)
				{
					_str[i] = '\0';
					_size = n;
				}
			}
		}
		size_t capacity() const
		{
			return _capacity;
		}
		void reserve(size_t n = 0)
		{
			if (n > _capacity)
			{
				char* newstr = new char[n + 1];
				// 避免浅拷贝,允许自定义类型的使用
				// 联系string(InputIterator first, InputIterator last)
				for (int i = 0; i < _size; i++)
				{
					newstr[i] = _str[i];
				}
				delete[] _str;
				_str = newstr;
				_capacity = n;
			}
	
		}
		void clear()
		{
			_str[0] = '\0';
			_size = 0;
		}
		bool empty() const
		{
			return _size == 0;
		}
		//Element access
		char& operator[] (size_t pos)
		{
			assert(pos <= _size);
			return _str[pos];
		}
		const char& operator[] (size_t pos) const
		{
			assert(pos <= _size);
			return _str[pos];
		}
		char& at(size_t pos)
		{
			assert(pos <= _size);
			return _str[pos];
		}
		const char& at(size_t pos) const
		{
			assert(pos <= _size);
			return _str[pos];
		}
		char& back()
		{
			return _str[_size - 1];
		}
		const char& back() const
		{
			return _str[_size - 1];
		}
		char& front()
		{
			return _str[0];
		}
		const char& front() const
		{
			return _str[0];
		}
	    //Modifiers:
		string& operator+= (char c)
		{
			push_back(c);
			return *this;
		}
		string& operator+= (const char* s)
		{
			insert(_size, s);
			return *this;
		}
		string& append(const char* s)
		{
			insert(_size, s);
			return *this;
		}
		void push_back(char c)
		{
			insert(_size, 1, c);
		}
		string& assign(const char* s)
		{
			clear();
			insert(0, s);
			return *this;
		}
		string& insert(size_t pos, size_t n, char c)
		{
			assert(pos <= _size);
			if (_size == _capacity)
			{
				size_t newcapacity = _capacity == 0 ? 4 : _capacity * 2;
				reserve(newcapacity);
			}
			size_t end = _size + n;
			while (end >= pos + n)
			{
				_str[end] = _str[end - n];
				end--;
			}
			for (int i = 0; i < n; i++)
			{
				_str[pos + i] = c;
			}
			_size++;
			return *this;
		}
		string& insert(size_t pos, const char* s)
		{
			assert(pos <= _size);
			size_t len = strlen(s);
			size_t newcapacity = len+_size;
			if (newcapacity > _capacity)
			{
				reserve(newcapacity);
			}
			size_t end = _size + len;
			while (end >= pos+len)
			{
				_str[end] = _str[end - len];
				end--;
			}
			for (int i = 0; i < len; i++)
			{
				_str[pos+i] = s[i];
			}
			_size += len;
			return *this;
		}
		string& erase(size_t pos = 0, size_t len = npos)
		{
			if (len > _size - pos)
			{
				len = _size - pos;
			}
			size_t end = pos + len;
			while (end <=_size)
			{
				_str[end - len] = _str[end];
				end++;
			}
			_size -= len;

			return *this;
		}
		void pop_back()
		{
			erase(_size - 1);
		}
		void swap(string& str)
		{
			std::swap(_str, str._str);
			std::swap(_size, str._size);
			std::swap(_capacity, str._capacity);
		}

		//String operations
		const char* c_str() const
		{
			return _str;
		}
		size_t find(char c, size_t pos = 0) const
		{
			assert(pos < _size);
			size_t i = pos;
			while (i <= _size - 1)
			{
				if (_str[i] == c)
				{
					return _str[i];
				}
			}
			return npos;
		}
		size_t find(const char* s, size_t pos = 0) const
		{
			assert(pos < _size);
			char* ptr = strstr(_str, s);
			if (ptr != nullptr)
			{
				return ptr - _str;
			}
			return npos;
		}
		string substr(size_t pos = 0, size_t len = npos) const
		{
			assert(pos < _size);
			if (len > _size - pos)
			{
				len = _size - pos;
			}
			string str(_str + pos, len);
			return str;
		}
	private:
		size_t _size;
		size_t _capacity;
		char* _str;
	public:
		static size_t npos;
	};
	size_t string::npos = -1;
	//Non-member function overloads
	void swap(string& s1, string& s2)
	{
		s1.swap(s2);
	}

	bool operator== (const string& lhs, const string& rhs)
	{
		return strcmp(lhs.c_str(), rhs.c_str()) == 0;
	}

	bool operator!= (const string& lhs, const string& rhs)
	{
		return !(lhs == rhs);
	}

	bool operator< (const string& lhs, const string& rhs)
	{
		return strcmp(lhs.c_str(), rhs.c_str()) < 0;
	}

	bool operator<= (const string& lhs, const string& rhs)
	{
		return lhs < rhs || lhs == rhs;
	}

	bool operator> (const string& lhs, const string& rhs)
	{
		return !(lhs <= rhs);
	}

	bool operator>= (const string& lhs, const string& rhs)
	{
		return !(lhs < rhs);
	}

	ostream& operator << (ostream& out, const string& str)
	{
		for (size_t i = 0; i < str.size(); i++)
		{
		    out << str[i];
		}
		return out;
	}

	istream& operator>>(istream& in, string& str)
	{
		str.clear();
		char c;
		char buffer[256];
		size_t i = 0;
		c = in.get();
		while (c != ' ' && c != '\n')
		{
			buffer[i++] = c;
			if (i == 255)
			{
				buffer[i] = '\0';
				str += buffer;
				i = 0;
			}
			c = in.get();

			c = in.get();
		}
		if (i > 0)
		{
			buffer[i] = '\0';
			str += buffer;
		}
		return in;
	}
	istream& getline(istream& is, string& str, char delim = '\n')
	{
		str.clear();

		int i = 0;
		char buffer[256];
		char ch;
		ch = is.get();
		while (ch != delim)
		{
			// 放到buff
			buffer[i++] = ch;
			if (i == 255)
			{
				buffer[i] = '\0';
				str += buffer;
				i = 0;
			}
			ch = is.get();
		}
		if (i > 0)
		{
			buffer[i] = '\0';
			str += buffer;
		}
		return is;
	}
}

二.vector

#pragma once

namespace hebre
{
	template<class T>
	class vector
	{

	public:
		typedef T* iterator;
		typedef const T* const_iterator;
		//Member functions
		vector()
		{}
		//initializer_list是一个类,支持迭代器
		//底层相当于开了一块数组的空间
		vector(initializer_list<T> il)
		{
			reserve(il.size());
			for (auto e : il)
			{
				push_back(e);
			}
		}
		// 这里的第一个参数必须是一个int类型
		// 如果参数类型是size_t的话
		// 调用函数会与vector(InputIterator first, InputIterator last)函数更加的适配
		// 编译器就会优先调用vector(InputIterator first, InputIterator last)函数
		// 我们如果使用int类型的话,才会更加适配 
		vector(int n, const T& val = T())
		{
			while (n--)
			{
				push_back(val);
			}
		}
		vector(const vector<T>& v)
		{
			size_t len = v.capacity();
			reserve(len);
			for (auto& e : v)
			{
				push_back(e);
			}
		}
        // 类模板的成员函数,也可以是一个函数模板。例如:list,string
		template <class InputIterator>
		vector(InputIterator first, InputIterator last)
		{
			while (first != last)
			{
				push_back(*first);
				first++;
			}
		}
		~vector()
		{
			delete[] _start;
			_start = nullptr;
			_finish = nullptr;
			_endofstorage = nullptr;
		}
		vector& operator= (const vector& x)
		{
			for (auto e : x)
			{
				push_back(e);
			}
			return *this;
		}

		//Iterators:
		iterator begin()
		{
			return _start;
		}
		iterator end()
		{
			return _finish;
		}
		const_iterator begin() const
		{
			return _start;
		}
		const_iterator end() const
		{
			return _finish;
		}
		//Capacity:
		size_t size()
		{
			return _finish - _start;
		}
		const size_t size() const
		{
			return _finish - _start;
		}
		void resize(size_t n, T val = T())
		{
			if (n <= size())
			{
				_finish = _start + n;
			}
			else
			{
				if (n > capacity)
				{
					reserve(n);
				}
				while (_finish < _start + n)
				{
					*_finish = val;
					++_finish;
				}
			}
		}
		size_t capacity() const
		{
			return _endofstorage - _start;
		}
		void reserve(size_t n)
		{
			if (n > capacity())
			{
				size_t oldsize = size();//size()在过程中会出错,因为_start会改变,_finish还保留着原来的值
				T* tmp;
				tmp = new T[n];
				if (_start)
				{
					// 浅拷贝,不能拷贝自定义类型
                    // memcpy(tmp, _start, sizeof(T) * oldSize);
					for (int i = 0; i < size(); i++)
					{
						tmp[i] = _start[i];
					}
					delete[] _start;
				}
				_start = tmp;
				_finish = _start + oldsize;
				_endofstorage = _start + n;
			}
		}
		bool empty() const
		{
			return _start == _finish;
		}
		//Element access:
		T& operator[](size_t i)
		{
			assert(i < size());

			return _start[i];
		}
		const T& operator[](size_t i) const
		{
			assert(i < size());

			return _start[i];
		}
		T& at(size_t i)
		{
			assert(i < size());

			return _start[i];
		}
		const T& at(size_t i) const
		{
			assert(i < size());

			return _start[i];
		}
		T& front()
		{
			return _start[0];
		}
		const T& front() const
		{
			return _start[0];
		}
		T& back()
		{
			return _start[size() - 1];;
		}
		const T& back() const
		{
			return _start[size() - 1];
		}
		//Modifiers:
		iterator insert(const_iterator pos, const T& x)
		{
			assert(pos >= _start && pos <= _finish);
			size_t len = pos - _start;
			iterator p = _start + len;
			if (_finish == _endofstorage)
			{
				size_t len = p - _start;
				reserve(capacity() == 0 ? 4 : capacity() * 2);
				p = _start + len;
			}
			iterator i = _finish - 1;
			while (i >= p)
			{
				*(i + 1) = *i;
				--i;
			}
			*p = x;
			++_finish;
			return p;
		}
		iterator erase(iterator pos)
		{
			assert(pos >= _start && pos < _finish);
			iterator i = pos + 1;
			while (i < _finish)
			{
				*(i - 1) = *i;
				++i;
			}
			_finish--;
			return pos;
		}
		void push_back(const T& x)
		{
			insert(_finish, x);
		}
		void pop_back()
		{
			assert(!empty());
			--_finish;
		}
		void swap(vector<T>& x)
		{
			std::swap(_start, x._start);
			std::swap(_finish, x._finish);
			std::swap(_endofstorage, x._endofstorage);
		}
		void clear()
		{
			_finish = _start;
		}

	private:
		iterator _start = nullptr;
		iterator _finish = nullptr;
		iterator _endofstorage = nullptr;
	};
	//Non-member function overloads
	template <class T>
	void swap(vector<T>& x, vector<T>& y)
	{
		x.swap(y);
	}
	template<class T>
	void swap(T& x, T& y)
	{
		std::swap(x, y);
	}
}

三.list

#pragma once

namespace hebre
{
	template<class T>
	struct list_node
	{
		T _data;
		list_node<T>* _prev;
		list_node<T>* _next;

		list_node(const T& val = T())
			: _data(val)
			, _next(nullptr)
			, _prev(nullptr)
		{}
	};

	template<class T,class Dereference,class Ptr>
	struct list_iterator
	{
		typedef list_node<T> Node;
		typedef list_iterator<T, Dereference, Ptr> Self;
		Node* _node;

		list_iterator(Node* node)
			:_node(node)
		{}
		Dereference operator*()
		{
			return _node->_data;
		}
		Ptr operator->()
		{
			return &_node->_data;
		}
		Self& operator++()
		{
			_node = _node->_next;
			return *this;
		}
		Self& operator--()
		{
			_node = _node->_prev;
			return *this;
		}
		Self operator++(int)
		{
			Self tmp(*this);
			_node = _node->_next;
			return tmp;
		}
		Self operator--(int)
		{
			Self tmp(*this);
			_node = _node->_prev;
			return tmp;
		}
		bool operator!=(const Self& s)
		{
			return _node != s._node;
		}
		bool operator==(const Self& s)
		{
			return _node == s._node;
		}
	};

	template<class T>
	class list
	{
		typedef list_node<T> Node;
	public:
		typedef list_iterator<T, T&, T*> iterator;
		typedef list_iterator<T, const T&, const T*> const_iterator;
		void empty_init()
		{
			_node = new Node();
			_node->_next = _node;
			_node->_prev = _node;
			_size = 0;
		}

		list()
		{
			empty_init();
		}
		template <class InputIterator>
		list(InputIterator first, InputIterator last)
		{
			empty_init();
			while (first != last)
			{
				push_back(*first);
				first++;
			}
		}
		//注意:n的数据类型必须是int,原因在上面的构造函数
		list(int n, const T& val = T())
		{
			empty_init();
			while (n--)
			{
				push_back(val);
			}
		}
		list(const list& x)
		{
			empty_init();
			for (auto e : x)
			{
				push_back(e);
			}
		}
		list(initializer_list<T> il)
		{
			empty_init();
			for (auto e : il)
			{
				push_back(e);
			}
		}
		~list()
		{
			clear();
			delete _node;
			_node = nullptr;
		}
		list<T>& operator=(list<T> lt)
		{
			swap(lt);
			return *this;
		}
		//Iterators:
		iterator begin()
		{
			return iterator(_node->_next);
		}
		const_iterator begin() const
		{
			return const_iterator(_node->_next);
		}
		iterator end()
		{
			return iterator(_node);
		}
		const_iterator end() const
		{
			return const_iterator(_node);
		}
		//Capacity:
		bool empty() const
		{
			return _node->_next == _node;
		}
		size_t size() const
		{
			return _size;
		}
		T& front()
		{
			return _node->_next;
		}
		const T& front() const
		{
			return _node->_next;
		}
		T& back()
		{
			return _node->_prev;
		}
		const T& back() const
		{
			return _node->_prev;
		}
		//Modifiers:
		template <class InputIterator>
		void assign(InputIterator first, InputIterator last)
		{
			while (first != last)
			{
				push_back(*first);
				first++;
			}
		}
		void push_back(const T& x)
		{
			insert(end(), x);
		}

		void push_front(const T& x)
		{
			insert(begin(), x);
		}

		void pop_front()
		{
			erase(begin());
		}

		void pop_back()
		{
			erase(--end());
		}
		iterator insert(iterator position, const T& val)
		{
			Node* cur = position._node;
			Node* newnode = new Node(val);
			Node* prev = cur->_prev;

			prev->_next = newnode;
			newnode->_prev = prev;

			newnode->_next = cur;
			cur->_prev = newnode;
			_size++;
			return iterator(newnode);
		}
		iterator erase(iterator position)
		{
			Node* cur = position._node;
			Node* next = cur->_next;
			Node* prev = cur->_prev;

			prev->_next = next;
			next->_prev = prev;
			_size--;
			delete cur;
			cur = nullptr;
			return iterator(prev);
		}
		void swap(list<T>& x)
		{
			std::swap(_node, x._node);
			std::swap(_size, x._size);
		}
		void resize(size_t n, T val = T())
		{
			if (n < _size)
			{
				size_t x = _size - n;
				while (x--)
				{
					pop_back();
				}
			}
			else
			{
				size_t x = n - _size;
				while (x--)
				{
					push_back(val);
				}
			}
		}
		void clear()
		{
			while (_node->_next != _node)
			{
				pop_back();
			}
		}
	private:
		Node* _node;
		size_t _size;
	};
}

四.stack

#pragma once
#include<deque>
namespace hebre
{
	template<class T, class Container = deque<T>>
	class stack
	{
	public:
		void push(const T& x)
		{
			_con.push_back(x);
		}

		void pop()
		{
			_con.pop_back();
		}

		const T& top() const
		{
			return _con.back();
		}

		T& top()
		{
			return _con.back();
		}

		size_t size() const
		{
			return _con.size();
		}

		bool empty() const
		{
			return _con.empty();
		}

		void swap(stack& x)
		{
			_con.swap(x);
		}
	private:
		Container _con;
	};
}

五.queue

#pragma once
#include<deque>

namespace hebre
{
	template<class T, class Container = deque<T>>
	class queue
	{
	public:
		void push(const T& val)
		{
			_con.push_back(val);
		}
		void pop()
		{
			_con.pop_front();
		}
		size_t size()
		{
			return _con.size();
		}
		T& front()
		{
			return _con.front();
		}
		const T& front() const
		{
			return _con.front();
		}
		T& back()
		{
			return _con.back();
		}
		const T& back() const
		{
			return _con.back();
		}
		bool empty()
		{
			return _con.empty();
		}
	private:
		Container _con;
	};
}

六.priority_queue

#pragma once
#include<deque>

namespace hebre
{
	//默认为升序排序
	template<class T, class Container = deque<T>>
	class priority_queue
	{
	public:
		void AdjustUp(int child)
		{
			int parent = (child - 1) / 2;
			while (child > 0)
			{
				if (_con[child] < _con[parent])
				{
					swap(_con[child], _con[parent]);
					child = parent;
					parent = (child - 1) / 2;
				}
				else
				{
					break;
				}
			}
		}
		void AdjustDown(int parent)
		{
			int child = parent * 2 + 1;
			while (child < _con.size())
			{
				if (child + 1 < _con.size() && _con[child] > _con[child + 1])
				{
					child++;
				}
				if (_con[parent] > _con[child])
				{
					swap(_con[child], _con[parent]);
					parent = child;
					child = parent * 2 + 1;
				}
				else
				{
					break;
				}
			}

		}
		void push(const T& val)
		{
			_con.push_back(val);
			AdjustUp(_con.size() - 1);
		}
		void pop()
		{
			swap(_con[0], _con[_con.size() - 1]);
			_con.pop_back();
			AdjustDown(0);
		}
		bool empty() const
		{
			return _con.empty();
		}

		T& top()
		{
			return _con[0];
		}

		const T& top() const
		{
			return _con[0];
		}

		size_t size() const
		{
			return _con.size();
		}
	private:
		Container _con;
	};
}

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

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

相关文章

SAM_Med2D 训练完成后boxes_prompt没有生成mask的问题

之前对着这这篇文章去微调SAM_Med2D(windows环境),发现boxes_prompt空空如也。查找了好长时间问题SAM-Med2D 大模型学习笔记&#xff08;续&#xff09;&#xff1a;训练自己数据集_sam训练自己数据集-CSDN博客 今天在看label2image_test.json文件的时候发现了一些端倪: 官方…

3.1 数据链路层功能概述

1、思维导图 2、数据链路层基本概念 结点:主机、路由器链路:网络中两个结点之间的物理通道&#xff0c;链路的传输介质主要有双绞线、光纤和微波。分为有线链路、无线链路。数据链路&#xff1a;网络中两个结点之间的逻辑通道&#xff0c;把实现控制数据传输协议的硬件和软件加…

vue面试题8|[2024-11-14]

问题1&#xff1a;什么是渐进式框架? vue.js router vuex element ...插件 vue.js 渐0 router 渐1 vuex 渐2 vue.js只是一个核心库&#xff0c;比如我再添加一个router或者vuex&#xff0c;不断让项目壮大&#xff0c;就是渐进式框…

使用TensorFlow实现简化版 GoogLeNet 模型进行 MNIST 图像分类

在本文中&#xff0c;我们将使用 TensorFlow 和 Keras 实现一个简化版的 GoogLeNet 模型来进行 MNIST 数据集的手写数字分类任务。GoogLeNet 采用了 Inception 模块&#xff0c;这使得它在处理图像数据时能更高效地提取特征。本教程将详细介绍如何在 MNIST 数据集上训练和测试这…

2.5D视觉——Aruco码定位检测

目录 1.什么是Aruco标记2.Aruco码解码说明2.1 Original ArUco2.2 预设的二维码字典2.3 大小Aruco二维码叠加 3.函数说明3.1 cv::aruco::detectMarkers3.2 cv::solvePnP 4.代码注解4.1 Landmark图说明4.2 算法源码注解 1.什么是Aruco标记 ArUco标记最初由S.Garrido-Jurado等人在…

java 根据 pdf 模板带图片文字生成pdf文件

在现代应用开发中,自动生成包含动态内容的 PDF 文档在电子发票、合同生成、表单填充等场景中有着广泛的应用。本文将介绍如何使用 iText 库动态填充 PDF 模板字段,并在指定位置插入签名和公章图片。 项目需求 假设我们有一个 PDF 模板文件,包含表单字段,如用户姓名、地址…

计算机网络-MSTP基础实验一(单域多实例)

前面我们已经大致了解了MSTP的基本概念和工作原理&#xff0c;但是我自己也觉得MSTP的理论很复杂不结合实验是很难搞懂的&#xff0c;今天来做一个配套的小实验以及一些配置命令。 一、网络拓扑 单域多实例拓扑 基本需求&#xff1a;SW1为VLAN10的网关&#xff0c;SW2为VLAN20的…

进程相关知识

#include <sys/types.h> #include <unistd.h> pid_t fork(void); 函数的作用&#xff1a;用于创建子进程。 返回值&#xff1a; fork() 的返回值会返回两次。一次是在父进程中&#xff0c;一次是在子进程中。 在父进程中返回创建的子进程的 ID, 在子进程中…

Python中的TCP

文章目录 一. 计算机网络1. 网络的概念2. IP地址① IP地址的概念② IP地址的表现形式③ IP地址的作用④ 网络查询命令Ⅰ. ifconfig/ipconfigⅡ. ping 3. 端口和端口号的概念(计算机通信原理)① 端口的概念② 端口号的概念 4. socket套接字① socket概念② socket使用场景 二. T…

本地部署Apache Answer搭建高效的知识型社区并一键发布到公网流程

文章目录 前言1. 本地安装Docker2. 本地部署Apache Answer2.1 设置语言选择简体中文2.2 配置数据库2.3 创建配置文件2.4 填写基本信息 3. 如何使用Apache Answer3.1 后台管理3.2 提问与回答3.3 查看主页回答情况 4. 公网远程访问本地 Apache Answer4.1 内网穿透工具安装4.2 创建…

【数据结构】线性表——栈与队列

写在前面 栈和队列的关系与链表和顺序表的关系差不多&#xff0c;不存在谁替代谁&#xff0c;只有双剑合璧才能破敌万千~~&#x1f60e;&#x1f60e; 文章目录 写在前面一、栈1.1栈的概念及结构1.2、栈的实现1.2.1、栈的结构体定义1.2.2、栈的初始化栈1.2.3、入栈1.2.4、出栈…

科技改变工作方式:群晖NAS安装内网穿透实现个性化办公office文档分享(1)

文章目录 前言1. 本地环境配置2. 制作本地分享链接3. 制作公网访问链接4. 公网ip地址访问您的分享相册5. 制作固定公网访问链接 前言 本文将详细介绍如何在群晖NAS上安装Synology Office和Synology Drive Server&#xff0c;并利用Cpolar内网穿透工具为本地文档配置固定的公网…

无插件H5播放器EasyPlayer.js网页web无插件播放器选择全屏时,视频区域并没有全屏问题的解决方案

EasyPlayer.js H5播放器&#xff0c;是一款能够同时支持HTTP、HTTP-FLV、HLS&#xff08;m3u8&#xff09;、WS、WEBRTC、FMP4视频直播与视频点播等多种协议&#xff0c;支持H.264、H.265、AAC、G711A、MP3等多种音视频编码格式&#xff0c;支持MSE、WASM、WebCodec等多种解码方…

rocketmq5源码系列--(一)--搭建调试环境

说在前头&#xff1a;阿里的rocketmq的文档是真他妈的烂的1b&#xff0c;很多东西都不说&#xff0c;全靠自己看源码&#xff0c;摸索&#xff0c;草&#xff0c;真的要吐血了 rocketmq的版本5而不是版本4&#xff0c;版本5比版本4多了个proxy rocketmq5 三个组件&#xff1a;…

【网页设计】CSS3 进阶(动画篇)

1. CSS3 2D 转换 转换&#xff08;transform&#xff09;是CSS3中具有颠覆性的特征之一&#xff0c;可以实现元素的位移、旋转、缩放等效果 转换&#xff08;transform&#xff09;你可以简单理解为变形 移动&#xff1a;translate旋转&#xff1a;rotate缩放&#xf…

django安装与项目创建

一、安装 在终端输入 pip install django //或者(&#xff09;指定安装版本 pip install django2.2 二、创建项目 2.1创建项目 django-admin startproject 项目名 2.2Django 项目中的关键文件 _init_.py:将目录标识为python包setting.py:核心配置文件&#xff0c;定义项目…

【redis】—— 初识redis(redis基本特征、应用场景、以及重大版本说明)

序言 本文将引导读者探索Redis的世界&#xff0c;深入了解其发展历程、丰富特性、常见应用场景、使用技巧等&#xff0c;最后会对Redis演进过程中具有里程碑意义的版本进行详细解读。 目录 &#xff08;一&#xff09;初始redis &#xff08;二&#xff09;redis特性 &#…

SpringBoot学习记录(三)之多表查询

SpringBoot学习记录&#xff08;三&#xff09;之多表查询 一、多表查询概述1、数据准备2、介绍3、分类 二、内连接三、外连接四、子查询1、标量子查询2、列子查询3、行子查询4、表子查询 三、案例1、准备环境2、需求实现3、&#xff08;附&#xff09;数据准备 一、多表查询概…

泰矽微重磅发布超高集成度车规触控芯片TCAE10

市场背景 智能按键和智能表面作为汽车智能化的重要部分&#xff0c;目前正处于快速发展阶段&#xff0c;电容式触摸按键凭借其操作便利性与小体积的优势&#xff0c;在汽车内饰表面的应用越来越广泛。对于空调控制面板、档位控制器、座椅扶手、门饰板、车顶控制器等多路开关的…

HarmonyOs学习笔记-布局单位

鸿蒙开发中布局存在很多单位 鸿蒙的默认单位是vp 下方先展示一下在RrkTsUI中我们应该怎么书写&#xff0c;然后讲一下各大单位具体的含义。 Text("这是一个文本, 用默认单位进行展示&#xff0c;也就是vp") .width(100) .height(100);//此段代码与上方代码是一样的…