补题之------后缀表达式(栈)

题目: 后缀表达式

来源:洛谷 P1449

链接:https://www.luogu.com.cn/problem/

题目描述:

所谓后缀表达式是指这样的一个表达式:式中不再引用括号,运算符号放在两个运算对象之后,所有计算按运算符号出现的顺序,严格地由左而右新进行(不用考虑运算符的优先级)。

本题中运算符仅包含 +-*/。保证对于 / 运算除数不为 0。特别地,其中 / 运算的结果需要向 0 取整(即与 C++ / 运算的规则一致)。

如:3*(5-2)+7 对应的后缀表达式为:3.5.2.-*7.+@。在该式中,@ 为表达式的结束符号。. 为操作数的结束符号。

输入格式

输入一行一个字符串 s,表示后缀表达式。

输出格式

输出一个整数,表示表达式的值。

样例一  输入:

3.5.2.-*7.+@

输出:

16

样例二 输入:

10.28.30./*7.-@

 输出:

-7

 

说明/提示

数据保证,1≤∣s∣≤50,答案和计算过程中的每一个值的绝对值不超过 1e9。

思路分析:
 
整体框架思路
         利用  stack s;  定义一个栈  s  。栈这种数据结构的特点是后进先出(LIFO),在处理后缀表达式时非常适用。因为后缀表达式的计算规则是遇到操作数就入栈,遇到操作符就从栈中取出相应数量的操作数进行计算,然后将结果再入栈,栈可以很好地管理操作数的存储和取出顺序
         在遍历字符串  a  的过程中 ,通过  if(a[i] >= '0' && a[i] <= '9')  判断当前字符是否为数字。如果是数字字符,就通过  c = c * 10 + a[i] - '0';  来构建完整的操作数。这里的原理是,对于多位数,比如  12  ,先读到  '1'  时, c  变为  1  ,再读到  '2'  时, c  就变为  1 * 10 + 2 = 12   ,实现了将字符形式的数字转换为整型数字。
 
操作数入栈:当遇到字符  '.'  时( if(a[i] == '.')  ) ,意味着一个完整的操作数已经读取完毕。此时将构建好的操作数  c  压入栈  s  中( s.push(c);  ) ,然后将  c  重置为  0 ( c = 0;  ) ,以便继续读取下一个操作数。
 
处理操作符思路
 
操作数出栈:当遇到操作符(如  + 、 - 、 * 、 /   ,以  if(a[i] == '+')  为例 )时,首先要从栈中取出操作数进行计算。因为栈是后进先出,所以先取出的是第二个操作数,后取出的是第一个操作数。通过  int x = s.top(); s.pop();  和  int y = s.top(); s.pop();  这两行代码,先取出栈顶元素赋值给  x  并弹出,再取出新的栈顶元素赋值给  y  并弹出 。其他的运算同理。
 

 
结果输出
 
当遍历完整个后缀表达式字符串后,此时栈中只剩下一个元素,这个元素就是整个后缀表达式计算的最终结果。 从栈顶取出这个结果并输出到标准输出,从而完成后缀表达式的计算过程。

实现代码:

#include
using namespace std;
const int N=1e7;
string a;
int main()
{
	cin>>a;
	stacks;
	int c=0;
	for(int i=0;i='0'&&a[i]<='9')
		{
			c=c*10+a[i]-'0';
		
		}
		if(a[i]=='.')
		{
			s.push(c);
			c=0;
		}
		if(a[i]=='+')
		{
			int x=s.top();	s.pop();
			int y=s.top();s.pop();
			s.push(y+x);
		}
		if(a[i]=='-')
		{
			int x=s.top();	s.pop();
			int y=s.top();	s.pop();
			s.push(y-x);
		}
		if(a[i]=='*')
		{
			int x=s.top();	s.pop();
				int y=s.top();	s.pop();
				s.push(y*x);
		}
		if(a[i]=='/')
		{
			int x=s.top();s.pop();
			int y=s.top();s.pop();
			s.push(y/x);
		}
	}
		cout<

通过对这段代码的详细剖析,希望大家能够更好地理解后缀表达式的计算原理及栈在其中的应用。

你可能感兴趣的:(算法,c++)