做四则运算的时候,需要将如下的算术表达式转化为后缀表达式,从而方便运算:
例如:
1+2/(3-4)+5*3 .............................. (为了表述简单起见,这里数字只能是[0-9]间的单个数字,运算符为"+-*/",括号"()")
转化后的结果:1234-/+53*+,转化为后缀表达式后,显然括号已经被消除,此时遍历后缀表达式,每次遇到运算符,取前面两个
数字进行运算即可!
中缀表达式转化为后缀表达式(逆波兰式)的算法思想如下:
数据结构:
前缀表达式串:const char* infix;
后缀表达式存放的位置: char* postfix;
存放运算符和括号的栈:stack<char> op;
算法步骤:
一、遍历前缀表达式串infix,对每一个字符ch
1) 当ch为空字符’ ‘, 忽略。
2) 当ch为数字[0-9],将ch存入后缀表达式postfix。
3) 当ch为运算符”+-*/”,如果符号栈中有优先级大于等于ch的符号,将栈中符号弹出并依次存入后缀表达式,最后将ch存入符号栈;
如果符号栈中没有先级大于等于ch的符号,直接将ch存入符号栈。
4) 当ch为左括号'(‘,将ch存入符号栈op。
5) 当ch为右括号’)’,将符号栈中的运算符依次出栈并存到后缀表达式中,直到遇到左括号'(‘,并将左括号出栈。
二、如果符号栈op不为空,将op中的符号依次出栈并存到后缀表达式postfix中。
附C++源码如下:
#include <iostream>
#include <stack>
using namespace std;
int priority(char op)
{
int r = 0;
switch(op)
{
case '(':
case ')':
r = 1;
break;
case '+':
case '-':
r = 2;
break;
case '*':
case '/':
r = 3;
break;
default:
break;
}
return r;
}
bool is_op(char op)
{
if(op == '+' || op == '-' || op == '*' || op == '/')
return true;
return false;
}
int infix_to_postfix(char* postfix, const char* infix)
{
stack<char> op;
const char* ptr = infix;
char* iter = postfix;
for(; *ptr != '\0'; ptr++)
{
char ch = *ptr;
if(ch == ' ')//skip whitespace
{
continue;
}
else if(ch >= '0' && ch <= '9')//number
{
*iter++ = ch;
}
else if( ch == '(')//left parentheses
{
op.push(ch);
}
else if( ch == ')')//rigth parentheses
{
//pop out all of the operators before left parentheses
while(1)
{
if(op.empty())
{
fprintf(stderr, "match parentheses error!\n");
return 0;
}
char temp = op.top();
op.pop();
if(temp == '(')
{
break;
}
else
{
*iter++ = temp;
}
}
}
else if(is_op(ch))//operators
{
//pop out all of the operators which priority is less than the current token!
while(!op.empty())
{
char temp = op.top();
if(priority(temp) >= priority(ch))
{
op.pop();
*iter++ = temp;
}
else
{
break;
}
}
op.push(ch);
}
else//unexpected token
{
fprintf(stderr, "unexpected token:%c!\n", ch);
}
}
//pop out all of the operators left in the stack
while(!op.empty())
{
char ch = op.top();
op.pop();
*iter++ = ch;
}
return 1;
}
int main(int argc, char** argv)
{
const char* infix="1+2/(3-4)+5*3";
char postfix[1024]={0};
if(infix_to_postfix(postfix, infix))
{
printf("%s\n", postfix);
}
system("pause");
return 0;
}