栈(stack)
栈是线性表的一种,是一种’先进后出"的类型。它只允许数据从一端进,从同一端出。类似物品的堆叠,将书一本一本地堆叠,与地面接触的表面积为一本书的面积,而高度就是所有书的厚度之和。然后拿书时只能从最高处开始拿(如果能轻易够到顶的话)。
栈的简单使用方法
在c++的STL中可以快速调用栈,当然自己写也可以。调用的方式如下:
#incldue<stack> //必要的头文件
stack<int>s; //创建一个整型栈
s.push(x); //将x压入栈
s.pop(); //将栈顶删除
s.top(); //查询栈顶,但不删除栈顶
s.empty(); //查询栈是否为空,为空时返回1
s.size(); //查询栈的大小
栈的使用方法基本同队列相同,只不过一个时“先进先出”,一个是“后进先出”
例题
下面通过例题来加强对栈的理解和使用。
(洛谷P1449)
后缀表达式
题目描述
所谓后缀表达式是指这样的一个表达式:式中不再引用括号,运算符号放在两个运算对象之后,所有计算按运算符号出现的顺序,严格地由左而右新进行(不用考虑运算符的优先级)。
如:
3*(5-2)+7
\texttt{3*(5-2)+7}
3*(5-2)+7 对应的后缀表达式为:
3.5.2.-*7.+@
\texttt{3.5.2.-*7.+@}
3.5.2.-*7.+@。在该式中,@
为表达式的结束符号。.
为操作数的结束符号。
输入格式
输入一行一个字符串 s s s,表示后缀表达式。
输出格式
输出一个整数,表示表达式的值。
样例 #1
样例输入 #1
3.5.2.-*7.+@
样例输出 #1
16
提示
数据保证, 1 ≤ ∣ s ∣ ≤ 50 1 \leq |s| \leq 50 1≤∣s∣≤50,答案和计算过程中的每一个值的绝对值不超过 1 0 9 10^9 109。
解题思路
首先我们要输入一个字符串,然后从头开始查询每一个字符,当遇到一个完整的数字时,我们将它压入栈,当遇到运算符号时,将拿最上方的两个数字进行运算,运算结束后再将运算结果压入栈(拿出来运算的数在栈中被删除了)。直到读到"@“字符时停止查询。题目用了”."来输入两位以上的数,所有需要特殊处理。
代码如下:
#include<iostream>
#include<stack>
#include<iostream>
using namespace std;
int main()
{
stack<int>sm;
string sa;
int xin1,xin2,xin3,a,b;
cin>>sa;
for(int i=0;i<sa.size();i++)
{
if(sa[i]<='9'&&sa[i]>='0')
{
a=b*10+sa[i]-'0';
b=a;
}
else if(sa[i]=='.')
{
sm.push(a);
b=0;
a=0;
}
else if(sa[i]=='+')
{
if(sm.empty()) continue;
xin1=sm.top();
sm.pop();
xin2=sm.top();
sm.pop();
xin3=xin1+xin2;
sm.push(xin3);
}
else if(sa[i]=='-')
{
if(sm.empty()) continue;
xin1=sm.top();
sm.pop();
xin2=sm.top();
sm.pop();
xin3=xin2-xin1;
sm.push(xin3);
}
else if(sa[i]=='*')
{
if(sm.empty()) continue;
xin1=sm.top();
sm.pop();
xin2=sm.top();
sm.pop();
xin3=xin1*xin2;
sm.push(xin3);
}
else if(sa[i]=='/')
{
if(sm.empty()) continue;
xin1=sm.top();
sm.pop();
xin2=sm.top();
sm.pop();
xin3=xin2/xin1;
sm.push(xin3);
}
else if(sa[i]=='@')
{
if(sm.empty()) continue;
xin1=sm.top();
cout<<xin1;
return 0;
}
}
return 0;
}