【C++】stack queue priority_queue ...

news2025/1/16 20:08:47

🌈感谢阅读East-sunrise学习分享——stack & queue & 容器适配器 & prioity_queue & 反向迭代器
博主水平有限,如有差错,欢迎斧正🙏感谢有你
码字不易,若有收获,期待你的点赞关注💙我们一起进步


🌈今天分享一个设计模式 — 容器适配器,而通过这个设计模式也诞生了许多重要的容器以及… 话不多说,干货满满,我们即刻启程🚀

目录

  • 一、stack的介绍和使用
    • 1.stack的介绍和使用
    • 2.经典题目
  • 二、queue的介绍和使用
  • 三、容器适配器
    • 1.什么是适配器
    • 2.适配器的使用
      • 3.2deque缺陷
      • 3.3选择deque作为stack和queue的底层默认容器
  • 四、stack和queue的模拟实现
    • 1.stack的模拟实现
    • 2.queue的模拟实现
  • 五、优先级队列
    • 1.priority_queue的介绍
    • 2.priority_queue的使用
    • 3.仿函数
    • 4.模拟实现
  • 六、反向迭代器
    • 1.反向迭代器的底层
    • 2.反向迭代器的模拟实现

一、stack的介绍和使用

1.stack的介绍和使用

✏️stack的文档介绍

  1. stack是一种容器适配器,专门用在具有后进先出操作的上下文环境中,其删除只能从容器的一端进行元素的插入与提取操作。
  2. stack是作为容器适配器被实现的(下文具体介绍),容器适配器即是对特定类封装作为其底层的容器,并提供一组特定的成员函数来访问其元素,将特定类作为其底层的,元素特定容器的尾部(即栈顶)被压入和弹出。

image-20230104160314298

stack的具体使用我们通过查看帮助文档便能清楚,我们之前的博客【数据结构】- 栈和队列也有过讲解,有了栈和队列的基础知识,对栈和队列的使用也更加的信手拈来了,这里博主就不对stack的使用进行过多赘述。

2.经典题目

📌最小栈

题目链接:155.最小栈

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wecqPRJe-1673334939847)(C:\Users\DongYu\AppData\Roaming\Typora\typora-user-images\image-20230104160743230.png)]

这道题的难点在于“在常数时间内检索到最小元素”🚩有的老铁就想着,定义一个变量咯,然后随时记录着,如果压栈的元素是目前栈中的最小元素,便更新

💥但是会有问题,我们的栈是也会pop的,当把目前你记录着的最小值给删了,那你又能怎么才能知道剩下的栈中元素的最小值是多少?

💥那不就得遍历,那遍历就无法符合它的时间复杂度要求了

所以以上的这个思路,只能记录一时,会有bug,那如何在有限的时间要求内又能实时地记录着最小元素 ---- 以空间换时间

🌏思路:

在创建题目要求的栈st的同时,我们再另外创建一个辅助栈minst(用于实现getMin)当我们在st.push( )时比较后把最小元素也压入minst中,在pop时两个栈也按要求弹栈,使得minst能随时和st保持一致,记录着栈中的最小元素

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RPJBtlo4-1673334939848)(C:\Users\DongYu\AppData\Roaming\Typora\typora-user-images\image-20230104162912356.png)]

📈小优化,为了更节省空间,我们可以在对minst压栈时判断一下,只在数据 <= 时才入栈,然后当stminst相同时再一起出栈

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jBdlufOK-1673334939848)(C:\Users\DongYu\AppData\Roaming\Typora\typora-user-images\image-20230104163430550.png)]

✏️

class MinStack {
public:
    MinStack() {

    }
    
    void push(int val) {
        st.push(val);

        if(minst.empty() || val <= minst.top())
            minst.push(val);
    }
    
    void pop() {
        //注意要先判断删除minst,再删除st,如果顺序颠倒会bug
        if(st.top() == minst.top())
            minst.pop();
        st.pop();
    }
    
    int top() {
        return st.top();
    }
    
    int getMin() {
        return minst.top();
    }
private:
    //保存栈中的元素
    std::stack<int> st;
    //保存栈的最小元素
    std::stack<int> minst;

};

二、queue的介绍和使用

✏️queue的文档介绍

  1. 队列是一种容器适配器,专门用于在FIFO上下文(先进先出)中操作,其中从容器一端插入元素,另一端提取元素。
  2. 队列作为容器适配器实现,容器适配器即将特定容器类封装作为其底层容器类,queue提供一组特定的成员函数来访问其元素。元素从队尾入队列,从队头出队列。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XAi6Alr1-1673334939848)(C:\Users\DongYu\AppData\Roaming\Typora\typora-user-images\image-20230104165453339.png)]

三、容器适配器

1.什么是适配器

在了解适配器之前,我们先了解:什么是设计模式

设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结

简单地说:通过长久的实践,总结出来的一种能够高效率、优效果解决需求目的的一种套路模式

比如我们之前学过的迭代器,在STL库中所有容器都有迭代器,因为迭代器好啊,迭代器也有被统一为:迭代器模式

迭代器模式:不暴露底层细节,封装后提供统一的方式访问容器

同理,适配器是一种设计模式,该模式是将已有的东西封装转换出你想要的东西🎈

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wUE0P6b2-1673334939849)(C:\Users\DongYu\AppData\Roaming\Typora\typora-user-images\image-20230104170228689.png)]

2.适配器的使用

在上文对stack和queue的介绍中已经有提到,这两个容器不叫容器,准确来说是称为“容器适配器”正是因为他们是通过容器适配器这一设计模式实现的🎈

而到目前为止我们已经学过了不少容器,那么我们是否能自己实现呢?

拿queue为例子,在实现之前我们应该先考虑queue有什么需求

  • 判空操作
  • 返回队头元素的引用
  • 返回队尾元素的引用
  • 在队列尾部入队列
  • 在队列头部出队列

看到这些操作,特别是头删,我们便想起上一篇博客对vector和list的优缺点的比较,我们选择list更为合适📌

namespace qdy
{
	template<class T, class Container = list<T>>//模板参数使用缺省值,创建queue时便不用多传一个参数
	class queue
	{
	public:
		void push(const T& x)
		{
			_con.push_back(x);
		}

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

		const T& front()
		{
			return _con.front();
		}

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

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

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

💭💭那stack呢?stack的对数据进行改动的需求好像就只是尾插尾删而已,而根据我们之前对list和vector的优缺点比较,stack底层的结构好像用vector更好一些,那这岂不是还得重新再换成vector的💤

这时我们就想着,要是能有一种容器,能兼具vector和list的优点就好了,当需要使用容器适配器时就用它🎈

你别说,诶你真别说,还真有🎯——deque

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ro1RqVq5-1673334939849)(C:\Users\DongYu\AppData\Roaming\Typora\typora-user-images\image-20230105131152044.png)]

3.2deque缺陷

与vector比较,deque的优势是:头部插入和删除时,不需要搬移元素,效率特别高,而且在扩容时,也不需要搬移大量的元素,因此其效率是必vector高的

与list比较,其底层是连续空间,空间利用率比较高,不需要存储额外字段

但是,deque有一个致命缺陷:不适合遍历,因为在遍历时,deque的迭代器要频繁的去检测其是否移动到某段小空间的边界,导致效率低下,而序列式场景中,可能需要经常遍历,因此在实际中,需要线性结构时,大多数情况下优先考虑vector和list,deque的应用并不多,而目前能看到的一个应用就是STL用其做stack和queue的底层数据结构

3.3选择deque作为stack和queue的底层默认容器

stack是一种后进先出的特殊线性数据结构,因此只要具有push_back()和pop_back()操作的线性结构,都可以作为stack的底层容器,比如vector和list都可以;queue是先进先出的特殊线性数据结构,只要具有push_back和pop_front操作的线性结构,都可以作为queue的底层容器,比如list。但是STL中对stack和queue默认选择deque作为其底层容器,主要是因为:

  1. stack和queue不需要遍历(因此stack和queue没有迭代器),只需要在固定的一端或者两端进行操作。
  2. 在stack中元素增长时,deque比vector的效率高(扩容时不需要搬移大量数据);queue中的元素增长时,deque不仅效率高,而且内存使用率高。

四、stack和queue的模拟实现

1.stack的模拟实现

namespace qdy
{
	template<class T,class Container = deque<T>>
	class stack
	{
	public:
		void push(cnost T& x)
		{
			_con.push_back(x);
		}

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

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

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

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

2.queue的模拟实现

namespace qdy
{
	template<class T, class Container = deque<T>>//模板参数使用缺省值,创建queue时便不用多传一个参数
	class queue
	{
	public:
		void push(const T& x)
		{
			_con.push_back(x);
		}

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

		const T& front()
		{
			return _con.front();
		}

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

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

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

五、优先级队列

1.priority_queue的介绍

  1. 优先级队列也是一种容器适配器,默认情况下它适配的容器是vector。底层结构是堆,并且默认情况下是大堆
  2. 优先级队列,虽然名字中有“队列”但是不符合队列“先进先出”的规则;优先级队列的特点是:优先级高的元素先出(由于默认是大堆,所以默认情况下,数据大的优先级就高)
  3. 附上堆的博客介绍[数据结构] - 堆和priority_queue的文档介绍✏️优先级队列以便于更深刻了解

2.priority_queue的使用

优先级队列默认使用vector作为其底层存储数据的容器,在vector上又使用了堆算法将vector中元素构造成堆的结构,因此priority_queue就是堆所有需要用到堆的位置,都可以考虑使用priority_queue。注意:默认情况下priority_queue是大堆。

函数声明接口说明
priority_queue( )/priority_queue(first, last)构造一个空的优先级队列
empty( )检测优先级队列是否为空,是返回true,否则返回false
top( )返回优先级队列中优先级最高的元素(堆顶元素)
push(x)在优先级队列中插入x
pop( )删除优先级队列中优先级最高的元素(堆顶元素)

✏️多说无益,实践出真知

链接:215.数组中第k个最大元素

📌方法一:建一个大堆然后popk次(时间复杂度:O(N+K*logN))

class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        priority_queue<int> pq(nums.begin(),nums.end());
        while(--k)
            pq.pop();
        return pq.top();
    }
};

📌方法二:建一个大小为k的小堆,进行比较大小,若数据比堆的数据大,则替换后入堆

时间复杂度:O(K+(N-K)*logK)

class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        //建k个小堆
        priority_queue<int,vector<int>,
        greater<int>> pq(nums.begin(),nums.begin()+k);
        //进行n-k次比较
        for(int i = k; i < nums.size(); ++i)
        {
            if(nums[i] > pq.top())
            {
                pq.pop();
                pq.push(nums[i]);
            }
        }
        return pq.top();
    }
};

💭💭看到方法二中,用priority_queue建小堆的写法不禁陷入了沉思…

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-n7Beqk6v-1673334939849)(C:\Users\DongYu\AppData\Roaming\Typora\typora-user-images\image-20230109170750924.png)]

上图是文档中优先级队列的介绍,前2个参数我们熟悉,也能知道底层默认是用vector来适配的,那第三个参数是什么?——仿函数

3.仿函数

仿函数的用处很多,今天我们通过优先级队列第一次接触到它,便来对其配合优先级队列进行简单地认识🎈

对于优先级队列来说,仿函数就像是一个灵活控制的开关,像上题的应用中,对于优先级队列我们有时候会想排小堆,有时候想排大堆;那系统封装了优先级队列的实现,总不能说直接去改代码逻辑吧?

所以priority_queue还提供了一个模板参数Compare,就是用于底层实现中创建堆的算法(系统默认调用less函数建大堆,所以如果我们是想建大堆则不需要传参)

🌏在之前使用C语言时,我们想要在函数调用时再传入函数进行算法调用,我们只能使用**“函数指针**”,但是函数指针的可读性实在是太差了,也无法支持泛型。于是在我们现在支持泛型模板时,便诞生了仿函数

仿函数实际上就是一个函数对象,是一个通过类实例化出的对象,然后由于在类中重载了operator( ),在调用此对象是就像在函数调用一样,可以像函数一样去使用——因此叫做仿函数✨

namespace qdy
{
	template<class T>
	class less
	{
	public:
		bool operator()(const T& a, const T& b)const
		{
			return a < b;
		}
	};

	template<class T>
	class greater
	{
	public:
		bool operator()(const T& a, const T& b)const
		{
			return a > b;
		}
	};
}

我们写一个类再对函数调用的“()”运算符进行重载,便能实现像函数调用一样的操作

int main()
{
	qdy::less<int> lsFunc;

	cout << lsFunc(1, 2) << endl;
	//等价于
	//cout << lsFunc.operator()(1,2) << endl;

	qdy::greater<int> gtFunc;
	cout << gtFunc(1, 2) << endl;
	
	return 0;
}

4.模拟实现

🎈priority_queue底层结构是堆,建大堆or小堆时要进行比较,因此需要使用仿函数(系统默认建大堆——调用less——若想建小堆——调用

namespace qdy
{
	template<class T>
	class less
	{
	public:
		bool operator()(const T& a, const T& b)const
		{
			return a < b;
		}
	};

	template<class T>
	class greater
	{
	public:
		bool operator()(const T& a, const T& b)const
		{
			return a > b;
		}
	};

	template<class T,class Container = vector<T>,class Compare = less<T>>
	class priority_queue
	{
	public:
		priority_queue()
		{}

		//迭代器构造
		template<class InputIterator>
		priority_queue(InputIterator first, InputIterator last)
			:_con(first,last)
		{
			//建堆
			for (int i = (_con.size() - 1 - 1) / 2; i >= 0; --i)
			{
				adjust_down(i);
			}
		}

		void adjust_down(size_t parent)
		{
			Compare com;
			size_t child = parent * 2 + 1;
			while (child < _con.size())
			{
				//if(child + 1 < _con.size() && _con[child] < _con[child + 1] )
				if (child + 1 < _con.size() && com(_con[child], _con[child + 1]))
					++child;
				
				//if(_con[parent] < _con[child)
				if (com(_con[parent], _con[child]))
				{
					swap(_con[parent], _con[child]);
					parent = child;
					child = parent * 2 + 1;
				}
				else
					break;
			}
		}

		void push(const T& x)
		{
			_con.push_back(x);
			adjust_up(_con.size() - 1);
		}

		void adjust_up(size_t child)
		{
			Compare com;
			size_t parent = (child - 1) / 2;
			while (child > 0)
			{
				//if(_con[parent] < _con[child])
				if (com(_con[parent], _con[child]))
				{
					swap(_con[parent], _con[child]);
					child = parent;
					parent = (child - 1) / 2;
				}
				else
					break;
			}
		}

		void pop()
		{
			swap(_con[0], _con[_con.size() - 1]);
			_con.pop_back();

			adjust_down(0);
		}

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

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

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

🌏如果T是自定义类型

  • 如果类中已支持比较大小,如:string类,我们可以直接使用

  • 如果此自定义类型是我们自己写的类的话,我们需要对其“<” “>”操作符进行重载

  • 假如原生的比较行为不是我们想要的,或是使用的是库里已经封装好的类但是不支持比较大小时,我们便需要写仿函数

六、反向迭代器

1.反向迭代器的底层

迭代器作为STL六大组件之一,其重要性在前文已经有涉及到;而迭代器除了const迭代器之外,还有一个重要的迭代器:反向迭代器

反向迭代器的实现同样也是使用了适配器模式🎈

在STL源码中对反向迭代器的实现,是通过正向迭代器进行构造

reverse_iterator rbegin(){return reverse_iterator(end());}
reverse_iterator rend(){return reverse_iterator(begin());}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1ZN9qqPw-1673334939850)(C:\Users\DongYu\AppData\Roaming\Typora\typora-user-images\image-20230110120541877.png)]

我们知道,在正向迭代器中,end( )是指向最后一个元素的下一个位置,而反向迭代器的实现为了追求对称,因此其rbegin( )同样如此

💭但是这样就会造成一个问题:当我们使用反向迭代器然后要解引用时,就会出现问题,因此在对反向迭代器的解引用运算符重载时要稍作修改

2.反向迭代器的模拟实现

namespace qdy
{
	template<class Iterator,class Ref,class Ptr>
	class Reverse_Iterator
	{
	public:
		Reverse_Iterator(Iterator it)
			:_it(it)
		{}

		Ref operator*()
		{
			Iterator tmp = _it;
			return *(--tmp);
		}

		Ptr operator->()
		{
			return &(operator*());
		}

		Reverse_Iterator& operator++()
		{
			--_it;
			return *this;
		}

		Reverse_Iterator& operator--()
		{
			++_it;
			return *this;
		}

		bool operator!=(const Reverse_Iterator& s)const
		{
			return _it != s._it;
		}
	private:
		Iterator _it;
	};
}

🌈🌈写在最后
我们今天的学习分享之旅就到此结束了
🎈感谢能耐心地阅读到此
🎈码字不易,感谢三连
🎈关注博主,我们一起学习、一起进步

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SAP ABAP增强 BADI的增强全解析

BADI的全称是Business Add-in&#xff0c;它的主要技术是基于ABAP的对象来实现增强。SAP中BADI的维护事务代码是SE18和SE19&#xff0c;SE18主要是创建及维护BADI对象&#xff0c;而SE19用于维护BADI的实例&#xff0c;即如何来实现BADI对象的功能。 SAP的BADI因系统版本的差别…

K8S Deployment 使用 更新 回滚 扩容

K8S Deployments 使用 & 更新 & 回滚 & 扩容 K8S Deployments 提供比 Replication Controller 、ReplicaSet 更高一级的抽象&#xff0c;也具备更丰富的功能。Deployment对象不仅创建pod&#xff0c;还确保集群中始终运行正确数量的pod&#xff0c;处理可伸缩性&a…

Esp8266+TFT太空人天气时钟

开源项目&#xff0c;只对动手能力有要求&#xff0c;有现成程序 b站演示视频: https://www.bilibili.com/video/BV1ND4y1W7oS/?spm_id_from333.999.0.0 效果图 模块和接线方法 使用ESP8266-12F模块&#xff0c;4M空间。OLED使用1.3寸IPS 240*240点阵彩屏&#xff0c;ST7789…

【Java集合】ArrayList源码分析

目录 一、ArrayList介绍 1.1 简介 1.2 继承体系 二、源码剖析 2.1 成员属性 2.2 构造方法 2.2.1 带int类型的构造方法&#xff1a;ArrayList(int initialCapacity) 2.2.2 无参构造方法&#xff1a;ArrayList() 2.2.3 Collection型构造方法&#xff1a;ArrayList(Collection c) …

flink规则引擎设计思路

在日常工作中我们经常收到一些诸如此类需求&#xff1a;“用户给点击了开屏广告&#xff0c;给用户下发私信”、“用户进入了推荐线&#xff0c;但在60秒内没有任何点击操作&#xff0c;弹框引导用户选择感兴趣的内容”、“用户点赞了某位作者的两篇以上的内容&#xff0c;但并…

C++入门----缺省参数和函数重载

C入门第一讲&#xff1a; 文章目录C入门第一讲&#xff1a;1.C关键字&#xff08;C98&#xff09;2.命名空间2.1命名空间的定义3.C的输入和输出4.缺省参数4.1缺省参数的概念4.2缺省参数的分类4.2.1全缺省参数4.2.2半缺省参数5.函数重载5.1函数重载的概念5.2C支持函数重载的原理…

在 SpringBoot 中 初步使用 MyBatis

这篇文章简单介绍如何初步使用MyBatis框架。MyBatis官网&#xff1a;mybatis – MyBatis 3 | 简介。本文中介绍MyBatis使用在SpringBoot中&#xff0c;Spring帮我们进行了管理&#xff0c;省去了获取sql的步骤。 什么是 MyBatis&#xff1f; MyBatis 是一款优秀的持久层框架&a…

XAML控件宽度为另一控件的一半、静态属性绑定、ObjectDataProvider

控件上当某些数据需要根据其他数据的变化而变化 很多时候&#xff0c;想让某个控件的宽度或者高度是另一个已有控件的一半&#xff0c;一开始打算使用ObjectDataProvider来实现&#xff0c;因为在控件上当某些数据需要根据其他数据的变化而变化时&#xff0c;可以使用ObjectDa…

Selenium实战【滑动验证码破解】【JAVA爬虫】

简介本文主要讲解&#xff0c;利用之前所学到的java selenium如何实战操作,浏览器控制鼠标&#xff0c;模拟人工操作滑动验证码。这里需要用javacv 的代码知识&#xff0c;用于计算图像中滑块需要移动的距离。实战目标网站&#xff1a;https://dun.163.com/trial/jigsaw操作流程…

【Java入门】Java注释和关键字

✅作者简介&#xff1a;CSDN内容合伙人、阿里云专家博主、51CTO专家博主、新星计划第三季python赛道Top1&#x1f3c6; &#x1f4c3;个人主页&#xff1a;hacker707的csdn博客 &#x1f525;系列专栏&#xff1a;Java入门 &#x1f4ac;个人格言&#xff1a;不断的翻越一座又一…

mycat个人详谈

项目背景 现在业务想实现不同的用户分别看到不同的数据库&#xff0c;领导说用mycat中间件试试。没有接触过这个东西&#xff0c;刚拿到手直接头皮发麻&#xff0c;现在搞定了&#xff0c;索性就记录一下 Mycat数据库分库分表中间件 简介 阿里大牛开发的开源免费产品&#x…

设计模式——抽象工厂模式

文章目录1. 抽象工厂模式的定义2. 抽象工厂模式的类图3. 抽象工厂模式的作用4. 抽象工厂模式的实现1. 抽象工厂模式的定义 提供一个接口&#xff0c;用于创建相关或依赖对象的家族&#xff0c;而不需要明确指定具体类。 抽象工厂允许客户使用抽象的接口来创建一组相关的产品&a…

OAuth 2.0简介

OAuth就是一种授权机制。数据的所有者告诉系统&#xff0c;同意授权第三方应用进入系统&#xff0c;获取这些数据。系统从而产生一个短期的、一定权限的令牌&#xff08;token&#xff09;&#xff0c;用来代替密码&#xff0c;供第三方应用使用。 流程 1.第三方客户端要求用…

【欧姆龙控制器NX1系列调研】

欧姆龙控制器NX1系列调研NX系列 NX1 CPU单元NX系列-EtherNet/IP耦合器单元NX系列-系统单元NX系列通信接口单元NX系列数字输入单元NX系列模拟量输入单元NX系列模拟量输出入单元NX系列 高速模拟量模块NX系列IO-Link 主站单元温度控制/温度输入单元位置接口单元NX系列 安全控制单元…

【algorithm】算法基础课---排序算法(附笔记 | 建议收藏)

&#x1f680;write in front&#x1f680; &#x1f4dd;个人主页&#xff1a;认真写博客的夏目浅石. &#x1f381;欢迎各位→点赞&#x1f44d; 收藏⭐️ 留言&#x1f4dd; &#x1f4e3;系列专栏&#xff1a;AcWing算法学习笔记 &#x1f4ac;总结&#xff1a;希望你看完…

CSS入门四、浮动

零、文章目录 文章地址 个人博客-CSDN地址&#xff1a;https://blog.csdn.net/liyou123456789个人博客-GiteePages&#xff1a;https://bluecusliyou.gitee.io/techlearn 代码仓库地址 Gitee&#xff1a;https://gitee.com/bluecusliyou/TechLearnGithub&#xff1a;https:…

mybatis参数配置和日志详解

生命周期和作用域是至关重要的&#xff0c;因为错误的使用会导致非常严重的并发问题 每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为核心的&#xff0c;SqlSessionFactory的实例可以通过 SqlSessionFactoryBuilder 获得&#xff0c;而 SqlSessionFactoryBuild…

【stl容器--实践操作】

目录&#xff1a;前言一、string&#xff08;一&#xff09;初始化 、 赋值 、 拼接&#xff08;二&#xff09;单个字符的访问和修改[]、at()&#xff08;三&#xff09;插入和删除insert 、erase&#xff08;四&#xff09;查找和替换find、rfind、replace&#xff08;五&…

代码随想录-47-101. 对称二叉树

目录前言题目1.递归思路2. 本题思路分析&#xff1a;3. 算法实现4. pop函数的算法复杂度5. 算法坑点前言 在本科毕设结束后&#xff0c;我开始刷卡哥的“代码随想录”&#xff0c;每天一节。自己的总结笔记均会放在“算法刷题-代码随想录”该专栏下。 代码随想录此题链接 题目…

FileNotFoundError: [Errno 2] No such file or directory VSCode Python插件的工作路径

文章目录1 前言2 Python主进程工作路径3 解决参考1 前言 在VSCode中&#xff0c;你是否遇到这样的情况 Traceback (most recent call last):File "......*.py", line 1, in <module>with open(filepath, r) as f: FileNotFoundError: [Errno 2] No such file…