当前位置: 首页>>算法&结构>>正文


中缀表达式转化为后缀表达式[附C++源码](原创)

做四则运算的时候,需要将如下的算术表达式转化为后缀表达式,从而方便运算:

例如:

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;
}
本文由《纯净天空》出品。文章地址: https://vimsky.com/article/75.html,未经允许,请勿转载。