837488 数据结构 1.栈

栈是计算机中经典的数据结构,简单的说,栈就是限制在一端进行插入删除操作的线性表。
栈有两种最重要的操作,即 pop(从栈顶弹出一个元素)和 push(将一个元素进栈)。
思想:先进后出,后进先出。可以理解为一些书,摆放时一本本堆起来,从低到高;取时从高到低一本本来取。
C++的STL库让我们更便利地写一个栈,而且空间开多少用多少,不必担心浪费。当然,手写栈也是可以的。

例题

Luogu 1739 表达式括号匹配
这道题数据简单,用一下栈的思想就能解决问题,不必写栈难多少。

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
char c;//输入的字符。本题中,除了两个括号和@,其他字符都没有用。 
int s;//记录括号的情况 
/*
“匹配”指的是(和)最终都能两两凑成一对。  
不匹配情况:(开头但是数目不相等, 如())
			)开头,如)()(,这一条出于惯性思维,我们不容易想到 
*/ 
int main(){
	do{
		cin>>c;
	//出现(则s=s+1来记录,出现)则s=s-1来记录。那么一对()可以实现“抵消” 
		if(c=='('&&s>-1)	s++;//表达式(出现而且它前面没有落单的) 
		if(c==')'&&s>=0)	s--;//前面无匹配或匹配正常 
		else if(c==')'&&s<0)	break;
	}while(c!='@');
//cin>>c是可以写在以c为条件的do while中的,有些神奇。 
	if(s==0)	cout<<"YES";//“抵消”成功,说明能匹配 
	else cout<<"NO";//只要s不为0,那么表达式括号匹配失败 
	return 0;
}

Luogu1427 小鱼的数字游戏
1.手写栈

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
#define MAXN 105
int top,a[MAXN],c; 
int main(){
	while(cin>>c){
		if(c==0)	break;//如果读入的是0那么不会将它存进数组,读入结束 
		else a[top++]=c;//在这种写法之下,数字从a[0]开始存储。
		//数组稍微开大一些可以防止越界 
	} 
	while(top>=1){
		cout<<a[--top]<<" ";
	} 
	return 0;
}

2.STL栈
1)vector

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<vector>
using namespace std;
vector<int>a;
int c;
//要注意vector是从a[0]开始存储a.size()个元素
int main(){
	while(cin>>c){
		if(c==0) break;
		a.push_back(c); 
	}
	while(!a.empty()){
		cout<<a.back() <<' ';
		a.pop_back() ;
		 /*
    这一部分输出也可以写成:
    for(int i=a.size()-1;i>=0;i--) //a.size()返回a中元素的个数
        cout<<a[i]<<" ";
    */
	}
	return 0;
}

2)stack

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<stack>//栈的头文件 
using namespace std;
stack<int>a;
int c;
int main(){
	while(cin>>c){
		if(c==0)	break;
		a.push(c); 
	} 
	while(!a.empty()){
		cout<<a.top()<<' ';//输出顶部元素 
		a.pop() ;//弹出顶部元素 
	}
	return 0;
}

Luogu5788 【模板】单调栈
stack

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<stack>
using namespace std;
#define MAXN 3000005
int n,a[MAXN],f[MAXN];
//a记录输入的数组,f记录答案 
stack<int>s;//s用于存储下标 
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]);
	for(int i=n;i>=1;i--){//从数组之中最后一个元素开始查找 
		while(!s.empty()&&a[s.top() ]<=a[i])
		//栈不为空而且栈顶元素比当前数小 
			s.pop() ;//弹出,反正之后也不会需要 
		f[i]=s.empty()?0:s.top();//记录答案 
		s.push(i); //当前i入栈 
	}
	//i=n的状态比较特殊,for只执行20行,自己可以模拟一下 
	for(int i=1;i<=n;i++)
		printf("%d ",f[i]);
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

延7488

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值