Reverse Polish Notation,即后缀表达式。
习惯上,二元运算符总是置于与之相关的两个运算对象之间,即中缀表达方法。波兰逻辑学家xxxxxxx于1929年提出了运算符都置于其运算对象之后,故称为后缀表达式。
如:中缀表达式:a+(b-c)*d
后缀表达式:abc-d*+
事实上,二元运算的前提下,中缀表达式可以对应一颗二叉树(中序遍历);逆波兰表达式即该二叉树后续遍历的结果如上面给出的两个例子可以通过如下图所示的二叉树得到
该结论对多元运算也成立,如“费运算”等
逆波兰表达式的计算
计算给定的逆波兰表达式的值。有效操作只有+-*/,每个操作数都是整数。
如:
拿到操作数的时候直接入栈,遇到操作符将前两个数出栈进行运算,运算结果入栈,然后继续。“2“,”1”,“+”,“3”,“*”:9-------------(2+1)*3
“4”,“13”,“5”,“/”,“+”:6---------------4+(13/5)
代码如下
bool IsOperator(const char* token)
{
return ((token[0] == '+') || (token[0] == '-')
|| (token[0] == '*') || (token[0] == '/'));
}
int ReverSePolishNotation(const char* str[], int size)
{
std::stack<int> s;
int a, b;
const char* token;
for (int i = 0; i < size; i++)
{
token = str[i];
if (!IsOperator(token))
{
s.push(atoi(token));
}
else
{
b = s.top();
s.pop();
a = s.top();
s.pop();
if (token[0] == '+')
{
s.push(a + b);
}
else if (token[0] == '-')
{
s.push(a - b);
}
else if (token[0] == '*')
{
s.push(a * b);
}
else if (token[0] == '/')
{
s.push(a / b);
}
}
}
return s.top();
}
int _tmain(int argc, _TCHAR* argv[])
{
const char* str[] = {"2", "1", "+", "3", "*"};
int value = ReverSePolishNotation(str, sizeof(str) / sizeof(const char*));
std::cout<<value<<std::endl;
system("pause");
return 0;
}
- 计算数学表达式的最常用方法
- 在实践中往往给出的不是立即数,而是变量名称,若经常计算且表达式本身不变,可以事先将中缀表达式转换成逆波兰表达式存储。