求逆波兰表达式

概述

逆波兰表达式即后缀表达式,即将每一运算符都置于其运算对象之后。逆波兰表达式是一种十分有用的表达式,它将复杂表达式转换为可以依靠简单的操作得到计算结果的表达式。例如(a+b)*(c+d)转换为ab+cd+。

思路

首先定义一个栈和一个队列,栈用于储存运算符,队列用于储存逆波兰表达式。读取字符时,若遇操作数直接加入队列,遇左括号直接压栈,遇右括号则将距离栈顶最近的左括号之间的运算符加入队列(右括号本身不压栈)。若遇运算符需要考虑优先级问题,加减运算符优先级较低,因此取栈顶除括号以外的运算符直接加入队列,直至栈空或遇上括号;乘除运算符优先级较高,因此将栈顶的乘和除运算符加入队列。即将栈内优先级高于当前运算符的元素加入队列,最后将当前运算符压栈。若完成上述步骤后栈内不为空,则将栈内元素依次弹出加入队列。

代码

void Reverse(char *buffer) {
    Stack s; // 用于储存运算符
    Queue q; // 用于储存逆波兰表达式
    InitStack(s);
    InitQueue(q);
    int i = 0;
    char ch;
    Push(s,buffer[i]);
    i++;
    // 假设该字符串是以#开始以#结束的
    while(buffer[i]!='#') {
        // 若buffer[i]为'('直接入栈
        if(buffer[i] == '(') {
            Push(s,buffer[i]);
        }
        // 若buffer[i]为')'则将距离栈顶最近的'('之间的运算符加入队列
        else if(buffer[i] == ')') {
            while(GetTop(s) != '(') {
                Pop(s,ch);
                EnQueue(q,ch);
            }
            // 舍弃')'
            Pop(s,ch);
        }
        // 若buffer[i]为+-*/则循环将栈顶元素弹出加入队列
        else if(buffer[i] == '+' || buffer[i] == '-') {
            for(ch = GetTop(s); ch != '#'; ch = GetTop(s)) {
                if(ch=='(')
                    break;
                else {
                    Pop(s,ch);
                    EnQueue(q,ch);
                }
            }
            Push(s,buffer[i]);
        }
        else if(buffer[i] == '*' || buffer[i] == '/') {
            for(ch = GetTop(s); ch != '#' && ch != '+' && ch != '-'; ch = GetTop(s)) {
                if(ch=='(')
                    break;
                else {
                    Pop(s,ch);
                    EnQueue(q,ch);
                }
            }
            Push(s,buffer[i]);
        }
        else {
            EnQueue(q,buffer[i]);
        }
        i++;
    }
    while(!StackEmpty(s)) {
        Pop(s,ch);
        EnQueue(q,ch);
    }
}

你可能感兴趣的:(数据结构)