后缀表达式
题目链接
题目描述
所谓后缀表达式是指这样的一个表达式:式中不再引用括号,运算符号放在两个运算对象之后,所有计算按运算符号出现的顺序,严格地由左而右新进行(不用考虑运算符的优先级)。
如:
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。
题解思路
后缀表达式(也称为逆波兰表达式)是一种数学表达式的表示方法,其中运算符在操作数之后。后缀表达式不依赖于括号来表示运算符的优先级,而是通过运算符的位置来确定运算的顺序。
根据后缀表达式的性质,我们在遇到数字的时候将数字根据顺序拼接计算好后再存储到栈里。当读到运算符时,将前两个数字取出进行运算,并将运算结果存入栈。需要注意的是,从栈中取出的第一个数运算时应该放在后面。
对栈还不太清楚的,可以先看下我写的 栈模板 。这道题可以使用C++的stl,也可以使用数组构造出来的栈结构,这道题与 栈模板 使用了同样的自定义类,但是根据题目需求,稍有更改。根据题目所给数据范围,本题使用 long long
就足够了,而且是有符号的数。
题解代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 100;
class MyStack
{
private:
int i = 0;
ll nums[N];
public:
void push(ll x)
{
if (i < N)
{
nums[i++] = x;
}
}
void pop()
{
if (i > 0)
{
i--;
}
}
ll top()
{
if (i > 0)
{
return nums[i - 1];
}
else
{
return -1;
}
}
int size()
{
return i;
}
};
MyStack st;
void cal(char c)
{
ll num2 = st.top();
st.pop();
ll num1 = st.top();
st.pop();
if (c == '+')
{
num1 = num1 + num2;
}
if (c == '-')
{
num1 = num1 - num2;
}
if (c == '*')
{
num1 = num1 * num2;
}
if (c == '/')
{
num1 = num1 / num2;
}
// printf("%lld\n", num1);
st.push(num1);
}
int main()
{
string s;
cin >> s;
ll num0 = 0;
for (int i(0); i < s.size(); ++i)
{
if (s[i] >= '0' && s[i] <= '9')
{
num0 = num0 * 10 + (s[i] - '0');
}
if(s[i] == '.')
{
st.push(num0);
num0 = 0;
}
if (s[i] == '+' || s[i] == '-' || s[i] == '*' || s[i] == '/')
{
cal(s[i]);
}
}
printf("%lld\n", st.top());
return 0;
}