3.1 模拟栈+表达式求值+模拟队列+单调栈

news2024/10/2 8:24:36

模拟栈

题目链接

栈的数组模拟非常简单,不详细描述
设置一个指针指向栈顶第一个元素即可

STL中stack实现已经更新在STL_Stack


#include<iostream>
#include<string>

using namespace std;

const int N=1e5+1;
int m;
string s;
int stack[N];
int p;//指针,指向栈顶元素 

int main(){
	
	cin>>m;
	p=0;//刚开始p=0说明栈内为空 
	while(m--){
		cin>>s;
		if(s=="push"){
			int x;
			cin>>x;
			stack[++p]=x;
		}
		else if(s=="pop"){
			p--;
		}
		else if(s=="empty"){
			if(p==0)
				cout<<"YES"<<"\n";
			else
				cout<<"NO"<<"\n";
		}
		else if(s=="query"){
			cout<<stack[p]<<"\n";
		}
	}
		
	return 0;
}

表达式求值***

思路:
关于表达式求值详解可见bilibili视频讲解
需要设置一个符号栈、一个数字栈
其中数字栈比较简单,只要扫描到数字直接入栈即可
对于符号栈,要注意若是空栈或者当前是左括号,符号直接可以进
每次扫描到符号想入栈时,如果扫描的符号优先级大于当前栈顶的元素,那么可以直接入栈(想象成优先级高的可以压住优先级低的),但是如果平级,即+和+、-和-这样的,那么就不能入栈,需要将符号栈中元素不断pop出直到能压住或者栈空(毕竟符号优先级相同,谁都不服谁,那么先入栈的先出去吧)
如果有符号出栈,那么就立即将其和数字栈中的数字组合,求得的值再次压入数字栈中
直到所有元素都被扫描完,然后把符号栈中的元素清理干净即可

实现代码

具体思路在代码中写的很清楚了


#include<iostream>
#include<string>
#include<algorithm>
#include<stack>
#include<unordered_map>

using namespace std;

stack <int> num_s;//数字栈 
stack <char> ope_s;//运算符栈 
unordered_map <char,int> h {{'+',1},{'-',1},{'*',2},{'/',2}};//定义优先级映射集 

void eval(){
	//计算、当有符号出栈时将其和数字栈中的元素结合计算
	//此时注意元素在栈中的顺序,因为对于除法来说a/b和b/a不一样 
	int a,b;//两个需要被运算的数字 
	char ope;//运算符 
	
	//第二个数字 
	b=num_s.top();
	num_s.pop();
	
	//第一个数字 
	a=num_s.top();
	num_s.pop();
	
	//运算符
	ope=ope_s.top();
	ope_s.pop(); 
	
	//进行运算
	int result;
	if(ope=='+')
		result=a+b;
	if(ope=='-')
		result=a-b;
	if(ope=='*')
		result=a*b;
	if(ope=='/')
		result=a/b;
	
	//将计算结果压入栈中 
	num_s.push(result); 
	
}
 


int main(){
	
	string s;
	cin>>s;//读取表达式 
		
	for(int i=0;i<s.size();i++){
		//从头扫描表达式 
		if(isdigit(s[i])){
			//isdigit()用于判断该元素是否为数字
			int j=i,x=0;
			//因为数字可能为多位数,因此需要用while读取,并且将字符串中的字符转为int以此用于计算 
			while(j<s.size()&&isdigit(s[j])){
				x=x*10+s[j]-'0';
				j++;
			}
			//读取完就将其放入栈中
			num_s.push(x);
			//此时j指向一个操作符,由于循环结束时i会++,因此这里需要将i的值设为j-1,
			//这样在i++后,下一次循环扫描的就是操作符了 
			i=j-1;
		}
		else if(s[i]=='('){
			//如果是左括号可以直接压入栈
			ope_s.push(s[i]); 
		}
		else if(s[i]==')'){
			//如果是右括号那么就要将左右括号中间所有的操作符弹出并计算
			while(ope_s.top()!='('&&!ope_s.empty()){//当栈顶不为'('且不为空 
				eval();//计算,计算的时候会自动pop符号 
			} 
			//最后要把'(' pop出去
			ope_s.pop(); 
		}
		else{
			//如果是操作符,那么就要判断操作符和栈顶元素优先级
			while(!ope_s.empty()&&h[ope_s.top()]>=h[s[i]]){
				//如果当前扫描的元素不比栈顶元素大,那么就要eval(弹出栈顶元素)直到s[i]能压住栈顶元素 
				eval();
			} 
			//如果扫描元素能够压住栈顶元素,那么直接入栈
			ope_s.push(s[i]); 
		}
	}	
	
	//扫描完了,处理符号栈中剩余元素
	while(!ope_s.empty()){
		eval();
	} 
	
	cout<<num_s.top()<<endl;
	
	return 0;
}

模拟队列

很简单,不多说
题目链接


#include<iostream>
#include<string>

using namespace std;

const int N=1e5+10;
int q[N];
int head=0;
int tail=0; 
int m;
string s;

int main(){
	
	cin>>m; 
	
	while(m--){
		cin>>s;
		if(s=="push"){
			int x;
			cin>>x;
			q[tail]=x;
			tail++;
		}
		if(s=="pop"){
			head++;
		}
		if(s=="empty"){
			if(head>=tail)
				cout<<"YES"<<endl;
			else
				cout<<"NO"<<endl;
		}
		if(s=="query"){
			cout<<q[head]<<endl;
		}
	}	
	
	return 0;
} 

单调栈***

题目链接

找到每个数字左边第一个比它小的。
如果用暴力做法:就是把每个数字左面的全部枚举一边。
但是考虑一下,每个数字左边的数字是否都有用呢。
假设a3>a5,那么a5后面的数字,左面第一个小的数,在a3和a5中只可能选a5,此时a3就没用了
因此我们只需要每个数字左侧的数字有一个递增的序列即可。

在这里插入图片描述


/*
遍历数列,将扫描到的数前面的所有数放在一个单调栈中
因为如果a3>a5,那么a5后面的数字,左面第一个小的数,在a3和a5中只可能选a5,此时a3就没用了
因此维护一个单调递增的栈 
*/
 
#include<iostream>
#include<stack>

using namespace std;

const int N=1e5+10;
int n; 
int a[N];
stack <int> s;//单调栈 

int main(){
	
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
	
	for(int i=1;i<=n;i++){
		if(s.empty()){
			cout<<-1<<" ";
			s.push(a[i]);
		}
		else if(s.top()<a[i]){
			//如果栈顶元素小,那么就直接输出,把当前元素加进去 
			cout<<s.top()<<" ";
			s.push(a[i]); 
		}
		else if(s.top()>=a[i]){
			//如果栈顶元素大,那么先找到栈中能满足要求的小的元素,然后再把扫描的元素输入
			while(!s.empty()&&s.top()>=a[i]){
				s.pop();
			}
			if(!s.empty()) 
				cout<<s.top()<<" ";
			else
				cout<<-1<<" ";
			s.push(a[i]);
		}
	}
	
	return 0;
} 

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

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

相关文章

Cartesi 2023 年 2 月回顾

2023年2月28日&#xff0c;通过ETH Denver和Cartesi的在线全球黑客马拉松一起开启黑客马拉松赛季!ETH Denver 正在热火朝天的进行着&#xff0c;我们正在为3月25日开始的首个全球在线黑客马拉松做准备。但这并不是本月发生的所有事情。我们在继续扩展和发展在全世界各地的社区&…

【软件测试】接口测试和接口性能测试,资深测试老鸟的总结......

目录&#xff1a;导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09;前言 只会独立使用工具&a…

程序员必备!最值得收藏的宝藏网站大盘点

做为程序员&#xff0c;没有收藏点宝藏网站都说不过去。 除了常见的大家熟知的知乎、谷歌、b站、CSDN、掘金等&#xff0c;今天将介绍一些其他更加实用的宝藏网站&#xff0c;程序员小伙伴们可以按需收藏哦&#xff5e; 1.菜鸟教程&#xff1a;https://www.runoob.com/ 国内…

大数据处理技术导论(6) | Datawhale组队学习46期

文章目录1. hive 概述2. hive 与传统关系型数据库的对比3. hive 数据类型4. hive 数据模型5. hive 实战5.1 创建表5.2 修改表5.3 清空表、删除表5.4 其他命令项目地址 https://github.com/datawhalechina/juicy-bigdata&#xff0c;感谢项目团队的付出。本次主要学习 hive 相关…

web,h5海康视频接入监控视频流记录三(后台node取流)

前端vue&#xff0c;接入ws视频播放 云台控制 &#xff0c;回放预览&#xff0c;都是需要调对应的海康接口。相当于&#xff0c;点击时&#xff0c;请求后台写好的接口&#xff0c;接口再去请求海康的接口 调用云台控制是&#xff0c;操作一次&#xff0c;不会自己停止&#x…

元宇宙如何在未来5年影响你的业务

自新冠疫情暴发以来&#xff0c;虽然数字经济的和实体经济受到了严重的冲击和影响&#xff0c;但这也加速了元宇宙在全球的发展。区块链、数字资产和非同质化代币&#xff08;NFTs&#xff09;的兴起进一步推动了世界对元宇宙的需求。元宇宙被定义为用户可以在其中进行互动的虚…

HiveSQL一天一个小技巧:如何将分组内数据填充完整?

0 需求1 需求分析需求分析&#xff1a;需求中需要求出分组中按成绩排名取倒数第二的值作为新字段&#xff0c;且分组内没有倒数第二条的时候取当前值。如果本题只是求分组内排序后倒数第二&#xff0c;则很简单&#xff0c;使用row_number()函数即可求出&#xff0c;但是本题问…

Netty之io.netty.util.concurrent.Promise与io.netty.util.concurrent.Future初解

目录 目标 Netty版本 Netty官方API 三者之间的关系 基本使用方法 java.util.concurrent.Future io.netty.util.concurrent.Future io.netty.util.concurrent.Promise 目标 了解io.netty.util.concurrent.Promise与io.netty.util.concurrent.Future的基本使用方法。了解…

操作系统权限提升(二十四)之Linux提权-明文ROOT密码提权

系列文章 操作系统权限提升(十八)之Linux提权-内核提权 操作系统权限提升(十九)之Linux提权-SUID提权 操作系统权限提升(二十)之Linux提权-计划任务提权 操作系统权限提升(二十一)之Linux提权-环境变量劫持提权 操作系统权限提升(二十二)之Linux提权-SUDO滥用提权 操作系统权限…

Netty学习(二):线程模型

目录 一、线程模型基本介绍 二、传统阻塞IO服务模型 2.1 工作原理图 2.2 模型特点 2.3 问题分析 三、Reactor模式 3.1 完善传统阻塞I/O服务模型 3.2 Reactor模型原理图 3.3 Reactor模式中核心组成 3.4 Reactor模式分类 四、单 Reactor 单线程 4.1 原理图 4.2 方案说…

(二十一)操作系统-信号量机制2

文章目录一、知识总览二、知识点回顾三、信号量机制实现进程互斥四、信号量机制实现进程同步五、信号量机制实现前驱关系六、总结一、知识总览 二、知识点回顾 整型信号量&#xff1a;用一个整数型的变量作为信号量&#xff0c;用来表示系统中某种资源的数量。   记录型信号量…

4.5 正则表达式过滤查询数据

文章目录1. 概述2. 基本字符匹配3.LIKE关键字与正则表达式的区别4.进行OR匹配5.匹配几个字符之一6.匹配范围7.匹配特殊字符8.匹配多个实例9.定位符1. 概述 正则表达式用来匹配更加复杂的查询条件&#xff0c;例如你想从文件中提取电话号码&#xff0c;想从查找名字中间有数字的…

带你掌握webSocket 和 socket.io的基本用法

两者的作用和区别 作用&#xff1a;使得前后端可以随时地相互沟通。什么是互相沟通呢&#xff1f;像网络请求这种就是客户端向服务端的单向的沟通&#xff0c;当然&#xff0c;网络请求也可以实现双向的沟通&#xff0c;比如ajax 轮询&#xff0c;就是浏览器开个定时器不断的发…

Python虚拟环境(pipenv、venv、conda一网打尽)[通俗易懂]

一、什么是虚拟环境 1. 什么是Python环境 要搞清楚什么是虚拟环境&#xff0c;首先要清楚Python的环境指的是什么。当我们在执行python test.py时&#xff0c;思考如下问题&#xff1a; python哪里来&#xff1f;这个主要归功于配置的系统环境变量PATH&#xff0c;当我们在命…

山地车和公路车怎么选

公路车&#xff1a; 只能适应平坦的路面&#xff0c;骑行阻力小&#xff0c;速度快比较适合新手 山地车&#xff1a; 能适应所有路面&#xff0c;更注重操控性和舒适性 怎么选&#xff1f; 1、先决定用途 旅游&#xff1a;旅行车、山地车、 通勤&#xff1a;公路车 2、预…

如何使用BeaconEye监控CobaltStrike的Beacon

关于BeaconEye BeaconEye是一款针对CobaltStrike的安全工具&#xff0c;该工具可以扫描正在运行的主动CobaltStrike Beacon。当BeaconEye扫描到了正在运行Beacon的进程之后&#xff0c;BeaconEye将会监控每一个进程以查看C2活动。 工作机制 BeaconEye将会扫描活动进程或Mini…

G公司对接伍尔特wurth EDI项目案例

项目背景 对伍尔特wurth 而言&#xff0c;与其供应商开展成功的数字化项目通常是以自动连接开始的。通过这种方式&#xff0c;标准化的信息可以在彼此之间进行简单而自动的交换。这个流程被称为电子数据交换&#xff08;EDI&#xff09;。 EDI使得诸如订单、送货单、发票、订单…

Jmeter常用断言之JSON断言简介

JSON断言可以对服务器返回的JSON文档进行验证。 JSON断言有两种使用模式&#xff1a; 1.根据JSONPath能否在JSON文档中找到路径&#xff1b; 2.根据JSONPath提取值并对值进行验证。 结果判定&#xff1a;若文档格式为非JSON则断言失败&#xff1b;找不到路径断言失败&#xff1…

深度学习 | BN层原理浅谈

深度学习 | BN层原理浅谈 文章目录深度学习 | BN层原理浅谈一. 背景二. BN层作用三. 计算原理四. 注意事项为什么BN层一般用在线性层和卷积层的后面&#xff0c;而不是放在激活函数后为什么BN能抑制过拟合(有争议)一. 背景 神经网络在训练时&#xff0c;由于内存限制&#xff0…

Swagger2实现配置Header请求头

效果 实现 大家使用swagger肯定知道在代码中会写一个 SwaggerConfig 配置类&#xff0c;如果没有这个类swagger指定也用不起来&#xff0c;所以在swagger中配置请求头也是在这个 SwaggerConfig 中操作。 1、要实现配置请求头在配置swagger的Docket的bean实例中添加一个 globa…