后缀表达式 / 逆波兰表达式

后缀表达式 / 逆波兰表达式


运算表达式:

  • a + b:中缀表达式 原因是运算符号在两个运算对象的中间。
  • + - a * b c d:前缀表达式 运算符在运算对象前面, 又称为波兰表达式。

  • a b c * - d +:后缀表达式运算符在运算对象后面, 又称为逆波兰表达式(RPN,Reversed Polish Notation)。

后缀表达式的优点 :


  • 1. 相较于前缀表达式更易于转换,最左边一定为数字。
  • 2. 不用括号,依靠运算顺序确定运算符的优先级。
  • 3 .更符合计算机的计算方式。计算机通过从左至右读取后缀表达式,就可以将遇到的运算对象压入栈,在遇到运算符时就弹出两个运算对象,完成计算,再将结果压入栈。最后留在栈中的就是计算结果。

下面我就举一个最经典的例题:

后缀表达式 / 逆波兰表达式求解:


思想:

将后缀表达式存入数组,然后一一遍历。遇到数字(OP_NUM)压入栈,遇到运算符即符号(OP_SYMBOL)则将栈中的栈顶前两个元素出栈,另外栈顶元素是右操作数。计算出的结果继续压栈,直到整个数组遍历完,最后栈中剩余唯一的数就是计算结果。

这里写图片描述

代码实现:


#pragma once
#include <iostream>
using namespace std;

#include <vector>
#include <stack>
enum OP_TYPE  
{
    OP_SYMBOL,// 操作符
    OP_NUM, // 操作数
    OP_ADD,
    OP_SUB,
    OP_MUL,
    OP_DIV,
};

struct Cell
{
    OP_TYPE _type;//类型 : OP_SYMBOL操作符 OP_NUM操作数
       int _value;//OP_SYMBOL的值都有:OP_ADD OP_SUB OP_MUL OP_DIV
}; 

class RPN
{
public:
    RPN(Cell* arr,size_t n)
    {
        _rpn.reserve(n);//开一个n大小的空间,不初始化
        for(size_t i = 0; i < n; ++i)
        {
            _rpn.push_back(arr[i]);
        }
    }

    int count()
    {
        stack<int> s;
        for(size_t i=0; i < _rpn.size() ; ++i)
        {
            if(_rpn[i]._type == OP_NUM)// 如果类型是数字的话,就入栈
            {
                s.push(_rpn[i]._value);
            }
            else if(_rpn[i]._type == OP_SYMBOL)//如果是操作符,就出栈计算
            {
                // 两个操作数出栈并且计算后将结果入栈
                //出栈
                int right = s.top();
                s.pop();
                int left = s.top();
                s.pop();

                //计算并将结果入栈
                switch(_rpn[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();
    }
protected:
    vector<Cell> _rpn;
};
void TestRPN()
{
    Cell arr[] = {
        {OP_NUM, 12},
        {OP_NUM, 3},
        {OP_NUM, 4},
        {OP_SYMBOL, OP_ADD},
        {OP_SYMBOL, OP_MUL},
        {OP_NUM, 6},
        {OP_SYMBOL, OP_SUB},
        {OP_NUM, 8},
        {OP_NUM, 2},
        {OP_SYMBOL, OP_DIV},
        {OP_SYMBOL, OP_ADD},
    };

    RPN rpn(arr, sizeof(arr)/sizeof(Cell));
    cout<<"计算结果:"<<rpn.count()<<endl;
}
int main()
{
    TestRPN();
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_37941471/article/details/80800292