后缀表达式求值_掌握算法-栈应用-后缀表达式

假设我们有一个便携计算器并想要计算一趟外出购物的花费。为此,我们将一列数据相加并将结果乘以1.06,它是所购物品的价格以及附加的地方税。如果购物的各项花销为4.99,5.99和6.99,那么输入这些数据的自然的方式是

4.99 + 5.99+ 6.99 × 1.06 =

随着计算器的不同,这个结果或者是所要的答案19.05,或者是科学答案18.39。最简单的四功能计算器将给出第一个答案,但是许多先进的计算器是知道乘法的优先级是高于加法的。

另一方面,有些项是需要上税的而有些项则不是,因此,如果只有第一项和最后一项是要上税的,那么

4.99×1.06 + 5.99 + 6.99×1.06 =

将在科学计算器上给出正确的答案18.69而在简单计算器上给出的错误的答案19.37。科学计算器一般包括括号,因此我们总可以通过加括号的方法得到正确的答案,但是使用简单计算器我们需要记住中间结果。

该列的典型计算顺序可以是将4.99和1.06相乘并存为A1,然后将5.99和A1相加,再将结果存入A1。我们再将6.99和1.06相乘并将答案存为A2,最后将A1和A2相加并将最后结果放入A1。我们可以将这种操作顺序书写如下:

4.99 1.06 × 5.99 + 6.99 1.06 × +

这个记法叫做后缀(postfix)或逆波兰(reverse Polish)记法,其求值过程恰好就是我们上面所描述的过程。计算这个问题最容易的方法就是使用一个栈,当见到一个数时就把它推入栈中,再遇到一个运算符时就作用与从该栈中弹出的两个数上,将所得结果推入栈中。

代码如下:

#include #include #include using std::vector;using std::stack;using std::string;using std::endl;using std::cout;double getPostfixResult(string& PostfixStr){    vector items;    string item;    for(const auto &chr : PostfixStr){        if((chr >= '0' && chr <= '9') || chr == '.'){            item.push_back(chr);        }        if(chr == ' ' && !item.empty()){            items.emplace_back(item);            item.clear();        }        if(chr == '+' || chr == '-' || chr == '*' || chr == '/'){            items.emplace_back(string(1, chr));        }    }    stack myStack;    for(const auto &item : items){        try{            double num = std::stod(item);            myStack.push(num);        }        catch(std::exception e){            double num1 = myStack.top();            myStack.pop();            double num2 = myStack.top();            myStack.pop();            if(item == "+"){                myStack.push(num2 + num1);            }            if(item == "-"){                myStack.push(num2 - num1);            }            if(item == "*"){                myStack.push(num2 * num1);            }            if(item == "/"){                myStack.push(num2 / num1);            }        }    }    return myStack.top();}int main(int argc, char const *argv[]){    string testStr = "4.99 1.06 * 5.99 + 6.99 1.06 * +";    cout << "result: " << getPostfixResult(testStr) << endl;    return 0;}
9568f8fbbdfd3880616135139ca2c8fc.png

计算一个后缀表达式花费的时间是O(N),因为对输入中的每个元素处理都是由一些栈操作组成从而花费时间。该算法的计算是非常简单。注意:当一个表达式以后缀记号给出时,没有必要知道任何优先规则。这是一个明显的优点。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值