【题解】P1449 后缀表达式

输入反而是最麻烦的)

思路

跟那道P1981表达式求值挺像的,这题就是把在里面的加减乘除放到了要算的数字后面,就拿例子来说:
3.5.2.-*7.+@
在这部分 3.5.2.-* 中我们可以看到3*(5–2)这个部分肯定是先算 - 号的,也就是说我们的运算顺序是按照在数字背后的运算符的顺序进行运算,先算的是 (5–2),也就是前面数字的最后两个进行减法运算,这就符合栈的规则,先进后出,值得注意的一点是要看清减数和被减数,是第二个出栈的减去第一个出栈的,除号也是如此,加号和乘号的话由于没有区别所以可以不用在意。
我们来模拟一次这个样例,新建一个栈s:
1. 将数字都入栈 3 5 2,直到碰到第一个运算符‘-’
2. 出栈两个数字, 5 2, 然后进行减法运算 5 - 2 = 3,然后把运算结果压回栈内,此时栈内的元素 3 3。
3. 继续读入,碰到第二个运算符‘*’,我们又出栈两个数字, 3 3, 然后进行乘法运算 3 * 3 = 9 ,将 9 压入栈内,此时栈内元素 9 。
4. 继续读入,遇到数字 7 ,将其压入栈内,直到遇到运算符‘+’,我们继续出栈两个数字 9 7 , 进行加法运算, 9 + 7 = 16 ,将其压入栈内,此时栈内元素 16 。
5. 读到字符‘@’,根据题意,结束读入,此时的栈顶元素 16 就是我们要的值!

我们来看下读入的部分

读入有很多种方法,比如
getchar()
就可以实现一个个字符读入
但是吧,老感觉很容易翻车,while循环加getchar一不小心就不知道读到那里去了。所以我个人推荐这种读一行字符的就还是用string方法直接cin来读入了。
string c; 
cin >> c;
//这样我们就拿一行字符串,然后在字符串的长度c.length()内来从头遍历到尾部。
for(int i = 0; i < c.length(); i++)
{
	//内容
}
以下是全部代码:
#include<iostream>
#include<stack>
using namespace std;
int n, m;

int main()
{
	stack<int> s;
	string c; cin >> c;
	//cnt用来记录数字,两个'.'之间的就是我们要压入的数字 
	int cnt = 0;
	for(int i = 0; i < c.length(); i++)
	{
		//碰上@表示结束,虽然这是字符串的最后一个字符,不要这行也行 
		if(c[i] == '@') break;
		//碰到'.'的时候就把目前这个数字cnt压入栈内 
		if(c[i] == '.')
		{
			s.push(cnt);
			//注意每次压入栈内都要进行清零操作 
			cnt = 0;
		 } 
		else if(c[i] == '*')
		{
			//取两个栈顶元素,进行运算符运算 
			int x = s.top();
			s.pop();
			int y = s.top();
			s.pop();
			cnt = x * y;
			s.push(cnt);
			cnt = 0;
		}
		else if(c[i] == '-')
		{
			int x = s.top();
			s.pop();
			int y = s.top();
			s.pop();
			//注意是出栈的第二个减去第一个 
			cnt = y - x;
			s.push(cnt);
			cnt = 0;
		}
		else if(c[i] == '+')
		{
			int x = s.top();
			s.pop();
			int y = s.top();
			s.pop();
			cnt = x + y;
			s.push(cnt);
			cnt = 0;
		}
		else if(c[i] == '/')
		{
			int x = s.top();
			s.pop();
			int y = s.top();
			s.pop();
			//注意是出栈的第二个除以第一个
			cnt = y / x;
			s.push(cnt);
			cnt = 0;
		}
		//还没碰到'.',进行数字的还原操作(因为我们是一个个字符遍历的 100 就要分成1 0 0来处理) 
		else
		{
			//以103.为例, cnt一开始为0 
			//1. 0 * 10 = 0; 0 + 1 = 1; 
			//2. 1 * 10 = 10; 10 + 0 = 0;
			//3. 10 * 10 = 100; 100 + 3 = 103;
			//4. 下一个就会碰到字符'.',我们就将此时的cnt压入栈内,并将cnt的值清0; 
			cnt *= 10;
			cnt += (c[i] - '0'); 
		}
	}
	//最后输出栈顶元素 
	cout << s.top() << endl;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值