【C++11数据结构与算法】C++ 栈

news2025/1/16 21:09:06

C++ 栈(stack)

文章目录

  • C++ 栈(stack)
    • 栈的基本介绍
    • 栈的算法运用
      • 单调栈
        • 实战题
          • LC例题:[321. 拼接最大数](https://leetcode.cn/problems/create-maximum-number/)
          • LC例题:[316. 去除重复字母](https://leetcode.cn/problems/remove-duplicate-letters/)

栈的基本介绍

CPP API: stack

  • 一种先进后出(FILO)的数据结构

  • 定义:stack <typedef> stack_name ;

  • 我们在初始化一个stack时,其中的类型也可以为标准库类型以及自定义类型,如果想创建一个包含多元素的类型应该如下定义:

    // 括号中所用的就是
    stack<pair<TreeNode*, int>> treeStack;
    
函数描述
(constructor)该函数用于构造堆栈容器。
empty该函数用于测试堆栈是否为空。如果堆栈为空,则该函数返回true,否则返回false。
size该函数返回堆栈容器的大小,该大小是堆栈中存储的元素数量的度量。
top该函数用于访问堆栈的顶部元素。该元素起着非常重要的作用,因为所有插入和删除操作都是在顶部元素上执行的。
push该函数用于在堆栈顶部插入新元素。
pop该函数用于删除元素,堆栈中的元素从顶部删除。
emplace该函数用于在当前顶部元素上方的堆栈中插入新元素。
swap该函数用于交换引用的两个容器的内容。
relational operators非成员函数指定堆栈所需的关系运算符。
uses allocator顾名思义,非成员函数将分配器用于堆栈。
#include <iostream>
#include <stack>
using namespace std;
void newstack(stack <int> ss)
{
	stack <int> sg = ss;
	while (!sg.empty())
	{
		cout << '\t' << sg.top();
		sg.pop();
	}
	cout << '\n';
}
int main ()
{
	stack <int> newst;
	newst.push(55);
	newst.push(44);
	newst.push(33);
	newst.push(22);
	newst.push(11);

	cout << "最新的堆栈是 : ";
	newstack(newst);
	cout << "\n newst.size() : " << newst.size();
	cout << "\n newst.top() : " << newst.top();
	cout << "\n newst.pop() : ";
	newst.pop();
	newstack(newst); 
	return 0;
}

关于push()和emplace():

  • push()函数接受一个参数,该参数是要添加到栈顶的元素的副本。

  • 当调用push()函数时,参数会被复制到栈中,即使元素是通过移动构造函数构造的也会发生复制。

  • emplace()函数接受的参数是用于构造栈顶元素的参数列表。

  • 当调用emplace()函数时,参数会被直接传递给栈顶元素的构造函数,避免了额外的复制操作。因此,emplace()通常比push()更高效。

  • 因此主要区别在于push()接受的是元素的值,而emplace()接受的是元素构造函数的参数列表。emplace()通常更灵活和高效,特别是当元素是通过移动构造函数构造时。

栈的算法运用

单调栈

栈内排序通常满足“单调递增”、“单调递减”,即栈中元素具备“单调性”

实战题
LC例题:321. 拼接最大数

在这个题目中,我们寻找数组的最大子串时,运用了单调栈的特性。但并非完全单调,以下,仅提供寻找最大子串func部分:

注意:这里的最大子串,指的是数组截选出来的子数组中元素相对位置不改变

vector<int> MaxSubNums(vector<int>& nums, int n)
	{
		// 如果为空,不用遍历
		if (n == 0) {
			return {};
		}
		stack<int> resStack;
		int pos = 0;
		while (pos < nums.size()) {
			// 余下+当前大小 > 目标大小
			if ((resStack.size() + nums.size() - pos) == n) break;

			// 如果栈为空
			if (resStack.empty()) {
				resStack.push(nums[pos]);
				pos++;
				continue;
			}
			// 如果栈满了 且大于栈顶
			if (resStack.size() == n) {
				if (nums[pos] > resStack.top()) {
					resStack.pop();
					continue;
				}
				else {
					pos++;
				}
			}
			if (resStack.size() < n) {
				// 小于等于,直接push
				if (nums[pos] <= resStack.top()) {
					resStack.push(nums[pos]);
					pos++;
				}
				else {
					resStack.pop();
				}
			}
		}
		while (resStack.size() < n && pos < nums.size()) {
			resStack.push(nums[pos]);
			pos++;
		}

		vector<int> result;
		while (!resStack.empty()) {
			result.push_back(resStack.top());
			resStack.pop();
		}
		std::reverse(result.begin(), result.end());
		return result;
	}
LC例题:316. 去除重复字母

题目:给你一个字符串 s ,请你去除字符串中重复的字母,使得每个字母只出现一次。需保证 返回结果的字典序最小(要求不能打乱其他字符的相对位置)。

image-20240408145007629

解法:因为要使结果为字典序最小,我们利用单调栈性质,使其从底至上为升序(非完全)

我们需要一个map(strCount)用于记录余下字符串中,某字符剩余多少

还需要一个set用于记录栈中已存在哪些元素

遍历字符串,入栈规则:

  • 首先:strCount[cur]–

1、若当前字符cur已在栈中,略过,

2、若当前字符cur未在栈中:

  1. cur > stack.top() || stack.empty() ,跳到第3步。
  2. cur < stack.top()
    1. 如果栈顶元素之后还会出现,弹出
    2. 循环上述操作,直到 栈空 或者 cur > stack.top() 或者栈顶元素在之后不再出现,结束循环
  3. 入栈,并在set中记录

遍历完字符串后,栈底到栈顶的元素拼起来就是最终答案。

class Solution
{
public:
    string removeDuplicateLetters(string s)
    {
        // 判断该字符余下还有多少个
        unordered_map<char, int> strCount;
        // 判断栈中是否包含这个元素,如果有就不可以push
        unordered_set<char> inStack;

        for (auto c : s)
        {
            strCount[c]++;
        }
        // 单调栈,保持从栈底往上升序(非完全)
        stack<char> strStack;
        for (auto c : s)
        {
            // 当前字符剩余个数减1
            strCount[c]--;
            // 栈中已有该元素,遍历下一个
            if (inStack.count(c) != 0)
                continue;
            // 如果当前栈不为空 且  当前元素大于栈顶元素,且栈顶元素在剩余字符中还会出现
            while (!strStack.empty() && c < strStack.top() && strCount[strStack.top()] > 0)
            {
                inStack.erase(strStack.top());
                strStack.pop();
            }
            // 入栈
            strStack.push(c);
            // 记录该元素已经在栈中出现过
            inStack.insert(c);
        }
        string ans = "";
        while (!strStack.empty())
        {
            ans = strStack.top() + ans;
            strStack.pop();
        }
        return ans;
    }
};

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

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

相关文章

如何使用ERC-20与Sui Coin标准创建Token

区块链使用tokens作为传递价值的基本手段。它们可以是区块链的原生交换单位&#xff0c;也可以是应用中的交换单位&#xff0c;甚至可以在游戏世界中用作货币。tokens还支持Sui和其他区块链上的强大DeFi活动。 以太坊使用ERC-20标准来创建tokens&#xff0c;借用智能合约&…

VueRouter3学习笔记

文章目录 1&#xff0c;入门案例2&#xff0c;一些细节高亮效果非当前路由会被销毁 3&#xff0c;嵌套路由4&#xff0c; 传递查询参数5&#xff0c;命名路由6&#xff0c;传递路径参数7&#xff0c;路径参数转props8&#xff0c;查询参数转props9&#xff0c;replace模式10&am…

ChatGPT-4o, 腾讯元宝,通义千问对比测试中文文化

国内的大模型应用我选择了国内综合实力最强的两个&#xff0c;一个是腾讯元宝&#xff0c;一个是通义千问。其它的豆包&#xff0c;Kimi&#xff0c;文心一言等在某些领域也有强于竞品的表现。 问一个中文文化比较基础的问题,我满以为中文文化chatGPT不如国内的大模型。可事实…

【安装笔记-20240608-Linux-动态域名更新服务之YDNS】

安装笔记-系列文章目录 安装笔记-20240608-Linux-动态域名更新服务之YDNS 文章目录 安装笔记-系列文章目录安装笔记-20240608-Linux-动态域名更新服务之YDNS 前言一、软件介绍名称&#xff1a;YDNS主页官方介绍 二、安装步骤测试版本&#xff1a;openwrt-23.05.3-x86-64注册填…

基于协调过滤算法商品推荐系统的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;商品管理&#xff0c;论坛管理&#xff0c;商品资讯管理 前台账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;论坛&#xff0c;商品资讯&#xff0c;商家&#xff0c;商品 开发系统…

PyTorch学习6:多维特征输入

文章目录 前言一、模型说明二、示例1.求解步骤2.示例代码 总结 前言 介绍了如何处理多维特征的输入问题 一、模型说明 多维问题分类模型 二、示例 1.求解步骤 1.载入数据集&#xff1a;数据集用路径D:\anaconda\Lib\site-packages\sklearn\datasets\data下的diabetes.cs…

【C++ STL】模拟实现 string

标题&#xff1a;【C :: STL】手撕 STL _string 水墨不写bug &#xff08;图片来源于网络&#xff09; C标准模板库&#xff08;STL&#xff09;中的string是一个可变长的字符序列&#xff0c;它提供了一系列操作字符串的方法和功能。 本篇文章&#xff0c;我们将模拟实现STL的…

Polar Web【中等】写shell

Polar Web【中等】写shell Contents Polar Web【中等】写shell思路&探索EXP运行&总结 思路&探索 初看题目&#xff0c;预测需要对站点写入木马&#xff0c;具体操作需要在过程中逐步实现。 打开站点(见下图)&#xff0c;出现 file_put_contents 函数&#xff0c;其…

pdf文件如何防篡改内容

PDF文件防篡改内容的方法有多种&#xff0c;以下是一些常见且有效的方法&#xff0c;它们可以帮助确保PDF文件的完整性和真实性&#xff1a; 加密PDF文档&#xff1a; 原理&#xff1a;通过设置密码来保护PDF文档&#xff0c;防止未经授权的访问和修改。注意事项&#xff1a;密…

如何对stm32查看IO功能。

有些同学对于别人的开发板的资源&#xff0c;或者IO口&#xff0c;或者串口等资源不知道怎么分配。 方法1、看硬石、野火、正点原子的开发板&#xff0c;看下他们的例子&#xff0c;那个资源用什么。自己多看几个原理图&#xff0c;多看几个视频&#xff0c;做一下笔记。以后依…

通过无障碍控制 Compose 界面滚动的实战和原理剖析

前言 针对 Compose UI 工具包&#xff0c;开发者不仅需要掌握如何使用新的 UI 组件达到 design 需求&#xff0c;更需要了解和实现与 UI 的交互逻辑。 比如 touch 事件、Accessibility 事件等等。 Compose 中对 touch 事件的处理和原理&#xff0c;笔者已经在《通过调用栈快…

Point-LIO:鲁棒高带宽激光惯性里程计

1. 动机 现有系统都是基于帧的&#xff0c;类似于VSLAM系统&#xff0c;频率固定&#xff08;例如10Hz)&#xff0c;但是实际上LiDAR是在不同时刻进行顺序采样&#xff0c;然后积累到一帧上&#xff0c;这不可避免地会引入运动畸变&#xff0c;从而影响建图和里程计精度。此外…

NASA数据集——SARAL 近实时增值业务地球物理数据记录海面高度异常

SARAL Near-Real-Time Value-added Operational Geophysical Data Record Sea Surface Height Anomaly SARAL 近实时增值业务地球物理数据记录海面高度异常 简介 2020 年 3 月 18 日至今 ALTIKA_SARAL_L2_OST_XOGDR 这些数据是近实时&#xff08;NRT&#xff09;&#xff…

【稳定检索/投稿优惠】2024年材料科学与能源工程国际会议(MSEE 2024)

2024 International Conference on Materials Science and Energy Engineering 2024年材料科学与能源工程国际会议 【会议信息】 会议简称&#xff1a;MSEE 2024大会地点&#xff1a;中国苏州会议官网&#xff1a;www.iacmsee.com会议邮箱&#xff1a;mseesub-paper.com审稿结…

WPF音乐播放器 零基础4个小时左右

前言&#xff1a;winfrom转wpf用久的熟手说得最多的是,转回去做winfrom难。。当时不明白。。做一个就知道了。 WPF音乐播放器 入口主程序 FontFamily"Microsoft YaHei" FontSize"12" FontWeight"ExtraLight" 居中显示WindowStartupLocation&quo…

【越界写null字节】ACTF2023 easy-netlink

前言 最近在矩阵杯遇到了一道 generic netlink 相关的内核题&#xff0c;然后就简单学习了一下 generic netlink 相关概念&#xff0c;然后又找了一到与 generic netlink 相关的题目。简单来说 generic netlink 相关的题目仅仅是将用户态与内核态的交互方式从传统的 ioctl 变成…

以sqlilabs靶场为例,讲解SQL注入攻击原理【42-53关】

【Less-42】 使用 or 11 -- aaa 密码&#xff0c;登陆成功。 找到注入点&#xff1a;密码输入框。 解题步骤&#xff1a; # 获取数据库名 and updatexml(1,concat(0x7e,(select database()),0x7e),1) -- aaa# 获取数据表名 and updatexml(1,concat(0x7e,(select group_conca…

CSS函数: translate、translate3d的使用

translate()和translate3d()函数可以实现元素在指定轴的平移的功能。函数使用在CSS转换属性transform的属性值。实现转换的函数类型有&#xff1a; translate()&#xff1a;2D平面实现X轴、Y轴的平移translate3d()&#xff1a;3D空间实现位置的平移translateX()&#xff1a;实…

Spring Boot整合Jasypt 库实现配置文件和数据库字段敏感数据的加解密

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

idea如何根据路径快速在项目中快速打卡该页面

在idea项目中使用快捷键shift根据路径快速找到该文件并打卡 双击shift(连续按两下shift) -粘贴文件路径-鼠标左键点击选中跳转的路径 自动进入该路径页面 例如&#xff1a;我的实例路径为src/views/user/govType.vue 输入src/views/user/govType或加vue后缀src/views/user/go…