表达式计算
例如:
2 - 3 * 4 + 5 这个表达式
下面是按照后缀表达式来写的程序,即表达式在栈中存放的顺序是2,3,4,’-‘,’*’,5’+’ 的顺序存放,碰到数值就压入栈中,当碰到运算符时候,先存入栈,当下一个运算符压入栈时比较两个运算符的优先级,如果两个运算符优先级相同,就继续入栈,知道所有的数值和运算符都入栈然后再按顺序使用top()来取栈顶,取两个值,和一个运算符就计算再压入栈再重复前面的动作,知道栈内所有的元素都出栈;如果新的运算符优先级没有已经入栈的前一个运算符优先级高,就top()
栈顶,先计算前一个的运算符,再把结果入栈,继续前面的重复工作。
可以看出,出栈的条件就是新进的运算符的优先级低于已经入栈的上一个运算符,意味着只要你后面的级别低于我,我就先把我能算的算完,把我算后的结果给你们后辈拿去运算。
enum Cal_Type //枚举
{
OP_NUM,
OP_SYMBOL,
OP_ADD,
OP_SUB,
OP_MUL,
OP_DIV,
};
struct Cell
{
Cal_Type _type; // 类型
int _value; // 值
Cell(Cal_Type type, int value)
:_type(type)
,_value(value)
{}
};
class Calculator
{
public:
Calculator(const vector<Cell>&exp)
:_exp(exp)
{}
int PostCalCount()//后缀算法
{
stack<int>s;
for (size_t i = 0; i < _exp.size(); ++i)
{
if (_exp[i]._type == OP_NUM)
{
s.push(_exp[i]._value);
}
else
{
int right = s.top();
s.pop();
int left = s.top();
s.pop();
switch (_exp[i]._value)
{
case OP_ADD:
s.push(left + right);
break;
case OP_SUB:
s.push(left - right);
break;
case OP_MUL:
s.push(left * right);
break;
case OP_DIV:
s.push(left / right);
break;
default:
break;
}
}
}
return s.top();
}