阿龙学堂-中缀-后缀表达式的计算

1、简介

在数据结构中,有一种数据结构叫做:Stack,LIFO(Last In First Out),在这个结构中,有个后缀表达式计算,运用该数据结构进行计算。

栈是一种只允许一端操作的线性数据结构,具有LIFO(last in first out)的特点,具有广泛的应用,如我在游戏编程模式--命令模式(2)中使用栈的结构来实验撤销、重做功能。现在打算用栈结构来实现后缀表达式的计算。

后缀表达式也叫逆波兰表达式,其求值过程可以用到栈来辅助存储。

2、后缀表达式

后缀表达式,指的是不包含括号,运算符放在两个运算对象的后面,所有的计算按运算符出现的顺序,严格从左向右进行(不再考虑运算符的优先规则)。

例如 5+(2+3)*4 转换为后缀表达式为 523+4*+

3、后缀表达式的计算

规则:从左向右扫描,遇到数字压栈,遇到操作符,弹出栈顶的两个元素,先弹出的元素在右边,后弹出来的在左边,进行计算后,将结果压栈,再往后扫描,直到扫描结束,输出栈顶元素,即为最终结果。
523+4*+为例
5压栈 2压栈 3压栈 遇到+号,弹出3 2,计算2+3,将5压栈,此时栈为5 5,将4压栈,遇到*号,弹出4 5,计算5*4,将20压栈 此时栈为5 20 ,遇到+号,计算5+20,将25压栈,扫描结束,输出25。
以上就是计算过程。下面用C++编写代码,为了方便标记算式的结束,在末尾我们加上#,用来标识算式结束,这里我们只进行四则运算

#include <iostream>
#include <stack>
#include "string"
using namespace std;

int main()
{
    stack<int> a;
    string temp;
    cin >> temp;
    int i = 0;
    while (true)
    {
        if (temp[i]=='#') cout << a.top(); break;
        if (temp[i]<='9'&&temp[i]>='0') a.push(temp[i]-48);
        else
        {
            int x, y;
            y = a.top(); a.pop();
            x = a.top(); a.pop();
            switch (temp[i])
            {
            case '+':a.push(x + y); break;
            case '-':a.push(x - y); break;
            case '*':a.push(x * y); break;
            case '/':a.push(x / y); break;
            default:break;
            }
        }
        ++i;        
    }
    cin >> temp;
    return 0;
}

4、中缀表达式转后缀表达式

4.1、规则

中缀表达式a + b*c + (d * e + f) * g,其转换成后缀表达式则为a b c * + d e * f  + g * +。

转换过程需要用到栈,具体过程如下:

1)如果遇到操作数,我们就直接将其输出。

2)如果遇到操作符,则我们将其放入到栈中,遇到左括号时我们也将其放入栈中。

3)如果遇到一个右括号,则将栈元素弹出,将弹出的操作符输出直到遇到左括号为止。注意,左括号只弹出并不输出。

4)如果遇到任何其他的操作符,如(“+”, “*”,“(”)等,从栈中弹出元素直到遇到发现更低优先级的元素(或者栈为空)为止。弹出完这些元素后,才将遇到的操作符压入到栈中。有一点需要注意,只有在遇到" ) "的情况下我们才弹出" ( ",其他情况我们都不会弹出" ( "。

5)如果我们读到了输入的末尾,则将栈中所有元素依次弹出。

4.2、实例

规则很多,还是用实例比较容易说清楚整个过程。以上面的转换为例,输入为a + b * c + (d * e + f)*g,处理过程如下:

1)首先读到a,直接输出。

2)读到“+”,将其放入到栈中。

3)读到b,直接输出。

4)读到“*”,因为栈顶元素"+"优先级比" * " 低,所以将" * "直接压入栈中。

5)读到c,直接输出

6)读到" + ",因为栈顶元素" * "的优先级比它高,所以弹出" * "并输出, 同理,栈中下一个元素" + "优先级与读到的操作符" + "一样,所以也要弹出并输出。然后再将读到的" + "压入栈中。

7)下一个读到的为"(",它优先级最高,所以直接放入到栈中。

8)读到d,将其直接输出。

9)读到" * ",由于只有遇到" ) "的时候左括号"("才会弹出,所以" * "直接压入栈中。

10)读到e,直接输出。

11)读到" + ",弹出" * "并输出,然后将"+"压入栈中。

12)读到f,直接输出。

13)接下来读到“)”,则直接将栈中元素弹出并输出直到遇到"("为止。这里右括号前只有一个操作符"+"被弹出并输出。

14)读到" * ",压入栈中。读到g,直接输出。

15)此时输入数据已经读到末尾,栈中还有两个操作符“*”和" + ",直接弹出并输出。至此整个转换过程完成。程序实现代码后续再补充了。

4.3、转换的另一种方法

1)先按照运算符的优先级对中缀表达式加括号,变成( ( a+(b*c) ) + ( ((d*e)+f) *g ) )

2)将运算符移到括号的后面,变成((a(bc)*)+(((de)*f)+g)*)+

3)去掉括号,得到abc*+de*f+g*+

 

 

具体细节关注微信公众号   【阿龙学堂】

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章