C++第十三弹 -- STL之stack深度剖析与模拟实现

news2024/9/24 15:18:05

文章索引

  • 前言
  • 1. stack的介绍
  • 2. stack的使用
  • 3. stack的模拟实现
  • 4. stackOJ题目
    • 4.1 最小栈
    • 4.2 栈的压入弹出序列
    • 4.3 用栈实现队列
  • 总结

前言

在现代C++编程中,STL(标准模板库)是一个不可或缺的工具。它提供了一套通用的模板类和算法,使得开发者能够更加高效地处理数据。本文将重点介绍STL中的stack容器,作为一种重要的顺序容器,stack遵循后进先出(LIFO,Last In First Out)的特性,广泛应用于函数调用、表达式求值等场景。通过深入了解stack的特性、基本操作及应用实例,读者将能够更好地掌握和应用这一重要的数据结构。

博客主页: 酷酷学!!!

感谢关注!!!


正文开始

1. stack的介绍

在这里插入图片描述

  1. stack是一种容器适配器, 专门用在具有后进先出操作的上下文环境中, 其删除只能从容器的一端进行元素的插入与提取操作.
  2. stack是作为容器适配器被实现的, 容器适配器即是对特定类作为其底层的容器, 并提供了一组特定的成员函数来访问其元素, 将特定类作为其底层的, 元素特定容器的尾部(即栈顶)被压入和弹出.
  3. stack的容器可以是任何形式的容器类模板或者一些其他特定的容器类, 这些容器类应该支持以下操作:
  • empty: 判空操作
  • back: 获取尾部元素操作
  • push_back: 尾部插入元素操作
  • pop_back: 尾部删除元素操作
  1. 标准容器vector, deque, list均符合这些需求, 默认情况下, 如果没有为stack指定特定的底层容器, 默认情况下使用deque.

在这里插入图片描述

2. stack的使用

在这里插入图片描述

重点:

在这里插入图片描述

代码演示:

#include<stack>
#include<iostream>
using namespace std;
int main()
{
	stack<int> st;
	st.push(1);
	st.push(2);
	cout << st.top() << endl;
	st.pop();
	cout << st.size() << endl;
	st.pop();
	cout << st.empty() << endl;
	return 0;
}

在这里插入图片描述

3. stack的模拟实现

从栈的接口中可以看出, 栈实际上是一种特殊的vector, 因此使用vector完全可以模拟实现stack.

#pragma once
#include<iostream>
#include<vector>
#include<list>
using namespace std;

namespace my
{
	//传统写法
	//template<class T>
	//class stack
	//{
	//private:
	//	T* _a;
	//	int _top;
	//	int _capacity;
	//};
	//直接复用容器
	template<class T, class Container = vector<T>> //当然适配器也可以是其他容器
	class stack
	{
	public:
		void push(const 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;
	};
}

4. stackOJ题目

4.1 最小栈

题目链接:最小栈

题目描述:

在这里插入图片描述

题目思路:

题目要求在常数时间内求出栈中最小元素, 如果我们遍历栈, 时间复杂度就为N, 不符合题目要求, 我们可以创建两个栈, 一个用来模拟入栈出栈, 一个用来记录最小数据, 定义两个栈为成员函数, 首先, 先插入一个元素, 然后让出栈序列与入栈的栈顶元素进行比较, 如果_minst为空或者栈顶元素小于或者等于_minst的栈顶元素, 则将数据push到最小栈, 出栈时, 如果_st的栈顶元素等于_minst的栈顶元素, 则_minst出栈, 即更改了当前最小元素.

在这里插入图片描述

代码演示:

class MinStack {
public:
    MinStack() {

    }
    
    void push(int val) {
        if(_minst.empty() || val <= _minst.top())
        {
            _minst.push(val);
        }
        _st.push(val);
    }
    
    void pop() {
        if(_st.top() == _minst.top())
        {
            _minst.pop();
        }
        _st.pop();
    }
    
    int top() {
        return _st.top();
    }
    
    int getMin() {
        return _minst.top();
    }

    stack<int> _st;
    stack<int> _minst;

};

/**
 * Your MinStack object will be instantiated and called as such:
 * MinStack* obj = new MinStack();
 * obj->push(val);
 * obj->pop();
 * int param_3 = obj->top();
 * int param_4 = obj->getMin();
 */

4.2 栈的压入弹出序列

题目链接:栈的压入弹出序列

题目描述:

在这里插入图片描述

题目思路

对于栈的压入弹出序列, 我们如果直接上手对比, 很容易出错, 而且比较麻烦, 我们可以对入栈与出栈进行栈的模拟, 创建一个栈st, 对入栈序列进行遍历插入, 先插入一个元素, 然后与出栈序列进行对比, 遍历出栈序列, 如果与出栈序列相等, 则说明该出栈了, 就pop出此时的栈, 这时还不能插入新的元素, 继续将st的栈顶元素与出栈序列对比, 如果不想等了, 我们再插入, 然后再进行下一轮的对比, 或者此时st已经为空了, 则跳出循环, 也进行下一轮的插入对比, 如果插入序列全部遍历完, 而出栈序列没有遍历完, 则说明此出栈序列不为栈的弹出序列, 反之亦然.也可以判断此时栈是否为空即可.
在这里插入图片描述

在这里插入图片描述

代码演示:

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param pushV int整型vector 
     * @param popV int整型vector 
     * @return bool布尔型
     */
    bool IsPopOrder(vector<int>& pushV, vector<int>& popV) {
        // write code here
        stack<int> st;
        int pos = 0;
        for(auto e : pushV)
        {
            st.push(e);
            while( !st.empty() && st.top() == popV[pos])
            {
                pos++;
                st.pop();
            }
        }
        return st.empty();
    }
};

4.3 用栈实现队列

题目链接:

用栈实现队列

题目描述:

在这里插入图片描述

题目思路

对于本题我们再栈的那一篇已经使用c语言完成过了, 本次我们采用C++进行完成, 避免了我们自己造轮子, 还是一样, 用两个栈实现一个队列, 一个栈进行插入, 如果需要出栈, 则就把所有的插入栈所有数据导一下,出栈直接出popst中的元素.

代码演示

class MyQueue {
public:
    MyQueue() {

    }
    
    void push(int x) {
        pushst.push(x);
    }
    
    int pop() {
        if(popst.empty())
        {
            while(!pushst.empty())
            {
                int x = pushst.top();
                popst.push(x);
                pushst.pop();
            }
        }
        int ret = popst.top();
        popst.pop();
        return ret;
    }
    
    int peek() {
        if(popst.empty())
        {
            while(!pushst.empty())
            {
                int x = pushst.top();
                popst.push(x);
                pushst.pop();
            }
        }
        int ret = popst.top();
        return ret;
    }
    
    bool empty() {
        return pushst.empty()&&popst.empty();
    }
    stack<int> pushst;
    stack<int> popst;

};

/**
 * Your MyQueue object will be instantiated and called as such:
 * MyQueue* obj = new MyQueue();
 * obj->push(x);
 * int param_2 = obj->pop();
 * int param_3 = obj->peek();
 * bool param_4 = obj->empty();
 */

总结

通过对STL中stack的探讨,我们认识到它在解决特定问题时的便利性和高效性。stack类提供了简单易用的接口,使得数据的插入和删除操作更加直接。同时,我们也了解了其在实际应用中的价值,例如在算法中用于管理临时状态或数据。此外,结合实际示例和代码实现,读者可以看到如何灵活地将stack应用于自己的项目中。掌握stack的使用,将为解决更复杂的问题奠定坚实的基础。希望本文能帮助大家更深入地了解STL之stack,并在日常编程中熟练运用


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

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

相关文章

Vue 2.x时间转换为北京时间(+8)

文章目录 当前时间格式效果图理想时间格式效果图转换方法总结 当前时间格式效果图 非中国常用时间格式&#xff0c;在上图中给可以看到&#xff0c;选择的时间为&#xff1a;2024-8-26 ~ 2024-8-27&#xff0c;返回结果却是&#xff1a;2024-08-25TXX:XX:XXZ&#xff0c;明显不…

C/C++开发神器CLion全新发布v2024.2——更适用于嵌入式开发

CLion是一款专为开发C及C所设计的跨平台IDE。它是以IntelliJ为基础设计的&#xff0c;包含了许多智能功能来提高开发人员的生产力。这种强大的IDE帮助开发人员在Linux、OS X和Windows上来开发C/C&#xff0c;同时它还使用智能编辑器来提高代码质量、自动代码重构并且深度整合CM…

教你识别原装与翻新芯片IC

在IC采购中&#xff0c;鉴别芯片真伪至关重要。原装芯片经过严格测试&#xff0c;而散新、翻新芯片可能存在质量和稳定性问题。市面上的IC芯片林林总总、各式各样&#xff0c;如果不注意区分&#xff0c;有时很难看出各种料有何不同。 假芯片制作手段包括翻新、打磨等&#xf…

2024年小红书图文制作超火爆风格,1单19.9!趣味性插画AI表情包项目思路

今天我想跟大家分享一个每天只需花20分钟就能轻松赚钱的AI表情包项目。 这个项目在小红书上非常受欢迎&#xff0c;因为它符合小红书的用户习惯&#xff0c;而且操作简单。下面我来详细讲讲如何利用软件快速创作有趣的插画&#xff01; 项目简介 这个项目的原理很简单&#x…

自助共享空间小程序怎么做 共享空间小程序系统开发制作方法

最近很多老板想要做一个自己公司的自助共享空间小程序系统&#xff0c;但是不知道该怎么做&#xff0c;本次瀚林就为大家详细介绍一下各种自助共享空间小程序系统的开发制作方法为大家做参考。 目前市面上的自助共享空间有很多类型例如常见的&#xff1a; 娱乐空间、棋牌室、共…

SpringBoot中MyBatis使用自定义TypeHandler

&#x1f604; 19年之后由于某些原因断更了三年&#xff0c;23年重新扬帆起航&#xff0c;推出更多优质博文&#xff0c;希望大家多多支持&#xff5e; &#x1f337; 古之立大事者&#xff0c;不惟有超世之才&#xff0c;亦必有坚忍不拔之志 &#x1f390; 个人CSND主页——Mi…

2-77 基于matlab-GUI的图像分割程序

基于matlab-GUI的图像分割程序&#xff0c;分别包括超像素 (superpixels)分割 SLIC算法&#xff0c;mean shift 图像分割&#xff0c;H算法&#xff08;Felzenszwalb和Huttenloch提出的图像分割算法&#xff09;&#xff0c;SEEDS&#xff08;Superpixels Extracted via Energy…

docker-compose单机部署rocketmq集群(双主双从,同步双写)

1.本文以RocketMQ 5.3.0 版本的镜像为例。 2.首先先更新docker&#xff0c;之前旧版docker&#xff0c;导致rocketmq一直起不来&#xff0c;一直报错。 3.安装docker-compose。 服务器环境&#xff08;目前只用192.168.25.135后期改ip地址即可&#xff09; | 1 | 192.168.…

ArcGIS图斑导出CAD后变成三维多段线?

欢迎关注同名微信公众号&#xff0c;更多文章推送&#xff1a; 正常情况下&#xff0c;将ArcGIS中的图层导出为CAD&#xff0c;生成的是闭合多段线&#xff1a; 导出的CAD&#xff1a; 但是有时候导出的CAD变成三维多段线&#xff1a; 三维多段线有多麻烦用过CAD画图的人应该都…

【GD32 MUC 移植教程】从 GD32F10x 移植到 GD32F30x

1. 前言 对于使用 GD32 系列微控制器进行产品开发的设计人员来说&#xff0c;因产品及功能升级&#xff0c;往往需要将一种微控制器替换成另一种微控制器&#xff0c;在保留既有功能的情况下增加新功能。为了更快地推出新产品&#xff0c;设计人员经常要将应用程序移植到新的…

【数据分享】1999—2022年地级市各类交通工具的客货运量和拥有量数据(Shp/Excel格式)

在之前的文章中&#xff0c;我们分享过基于2000-2023年《中国城市统计年鉴》整理的1999-2022年地级市的人口相关数据、各类用地面积数据、污染物排放和环境治理相关数据、房地产投资情况和商品房销售面积、社会消费品零售总额和年末金融机构存贷款余额、一般公共预算收支状况、…

Transformer模型-4-Inputs

Encoder的输入层和Decoder的输入层是一样的结构&#xff0c;都是由Token embedding&#xff08;词向量 word embedding&#xff09; 和 Positional embedding(位置向量) 组合而成&#xff0c;并到最终的 输入向量x。 Transformer引入Positional embedding主要是解决词序问题。…

开源程序实操:岩土工程渗流问题的有限单元法应用

有限单元法在岩土工程问题中应用非常广泛&#xff0c;很多商业软件如Plaxis/Abaqus/Comsol等都采用有限单元解法。尽管各类商业软件使用方便&#xff0c;但其使用对用户来说往往是一个“黑箱子”。相比而言&#xff0c;开源的有限元程序计算方法透明、计算过程可控&#xff0c;…

Linux configure.ac:51: error: possibly undefined macro: AC_MSG_ERROR

&#xff42;&#xff55;&#xff47;&#xff1a; 解决方法&#xff1a; cd /usr/local/share/autoconf/autoconf  cp *&#xff0e;m4 /usr/share/aclocal

编程语言中的特殊类的设计

文章目录 不能被拷贝的类只能在堆上创建对象的类:方式一方式二 设计类只能创建栈对象实现类, 不能被继承单例模式设计饿汉模式懒汉模式线程安全问题 不能被拷贝的类 c98 只声明(不生成, 编译器默认会生成, 有浅拷贝等的问题), 不实现, 并将其访问设为private c11使用delete来…

Python数据可视化库之bqplot使用详解

概要 在数据科学和机器学习领域,数据可视化是理解和分析数据的重要工具。bqplot 是一个基于 Jupyter Notebook 的 Python 可视化库,专注于交互式数据可视化。它结合了 D3.js 的强大功能和 Python 的易用性,使用户能够在 Jupyter 环境中创建丰富的交互式图表。bqplot 的设计…

如何使用GPT画出带中文的图和表?-已解决GPT画图表出现乱码的问题

众所周知&#xff0c;GPT的中文库有点问题&#xff0c;要求他画带中文的图或表存在中文的时候&#xff0c;就会出现乱码或者方框。 可以发现&#xff0c;GPT的中文库有问题&#xff0c;那么该如何解决这个问题呢&#xff1f; 直接在promote的时候上传你需要它使用的字体&…

高斯混合模型GMM

一、两个角度看GMM 1、从几何角度来看&#xff1a;加权平均值&#xff0c;多个高斯分布叠加而成 纵轴——f&#xff08;x&#xff09;概率密度函数&#xff0c;横轴——数据点 2、从混合模型角度看 x:observed variable z:latent variable →对应的样本是属于哪一个高斯分布&…

【SQL】筛选上级经理离职的员工

目录 题目 分析 代码 题目 表: Employees ----------------------- | Column Name | Type | ----------------------- | employee_id | int | | name | varchar | | manager_id | int | | salary | int | ----------------------- 在 SQ…

word文档合并样式问题

word协同工作时&#xff0c;在mac用office编辑后发送给对方进行合并时&#xff0c;出现了一些不该看到的样式。 需要注意的几点&#xff1a; 1、大家均需要使用同样的软件&#xff0c;如office&#xff0c;如果使用wps&#xff0c;会导致新增很多样式。 2、在样式窗格&#…