码迷,mamicode.com
首页 > 其他好文 > 详细

栈 之 求后缀表达式

时间:2015-12-03 00:39:49      阅读:186      评论:0      收藏:0      [点我收藏+]

标签:

最近学习了栈,为了巩固知识,照着书实现了一个有关于栈的应用的例子:将中缀表达式转化为后缀表达式。

这里先来明白什么是中缀表达式:我们正常使用的算式,如a + b * c 就是一个中缀表达式。中缀表达式的特点就是运算符在中间。

后缀表达式就是 运算符在后面,像上面的式子如果转化为后缀表达式就为  a b * + 。

这里以测试用例:A*B(B+C)-D/(E+F) 来为大家介绍一下转化的过程。

 

由中缀表达式中读取的字符

分解中缀表达式的过程

求后缀表达式的过程

栈中的内容

规则

A

 

A

 

将操作数A写至后缀(后缀表达式)

*

A*

A

*

若栈为空,将*进栈

(

A*(

A

*(

将操作数(入栈

B

A*(B

AB

*(

将操作数B写入后缀

+

A*(B+

AB

*

栈非空,故弹出一项

 

A*(B+

AB

*(

有(,故将(进栈

 

A*(B+

AB

*(+

将操作数+进栈

C

A*(B+C

ABC

*(+

将操作数C写入后缀中

)

A*(B+C)

ABC+

*(

遇见),弹出栈中的位于(之后的内容即+,写至后缀

 

A*(B+C)

ABC+

*

若有(,直接将其出栈

-

A*(B+C)

ABC+*

-

将*出栈,写入后缀,再将-进栈

D

A*(B+C)-D

ABC+*D

-

将D写入后缀

/

&-D/

&D

-/

将\进栈

(

&-D/(

&D

-/(

将(入栈

E

&-D/(E

&DE

-/(

将E写入后缀

+

&-D/(E+

&DE

-/

栈弹出一项

 

&-D/(E+

&DE

-/(

出栈的为(,因此将其重新进栈

 

&-D/(E+

&DE

-/(+

将+进栈

F

&-D/(E+F

&DEF

-/(+

将F写入后缀

)

&-D/(E+F)

&DEF

-/(

遇见),弹出栈中的位于(之后的内容即+,写至后缀

 

&-D/(E+F)

&DEF+

-/

遇见(,将其出栈

 

&-D/(E+F)

&DEF+/-

 

将剩下栈中的元素全部出栈,写入后缀

A*(B+C)-D/(E+F)

如果大家肯定还不太明白,大家可以自己百度一下,这里就不多做介绍了。

实现的算法就是上面的转化过程,下面是源码,包含解释:

1.栈类stackX

package infix;
/*
 * 这是一个自己定义的,存储数据的栈
 */
public class StackX {
    private int maxSize;
    private char[] stackArray;
    private int top;
    
    public StackX(int s){
        maxSize = s;
        stackArray = new char[maxSize];
        top = -1;
    }
    //入栈操作
    public void push(char value){
        stackArray[++top] = value;
    }
    //出栈操作
    public char pop(){
        return stackArray[top--];
    }
    //查看栈顶元素
    public char peek(){
        return stackArray[top];
    }
    //判断是是否为空
    public boolean isEmpty(){
        return (top == -1);
    }
    public int size(){
        return top+1;
    }
    //查看在位置n的元素
    public char peekN(int n){
        return stackArray[n];
    }
    //打印从栈底到栈顶的元素
    public void displayStack(String s){
        System.out.print(s);
        System.out.print("Stack (bottom-->top):");
        for (int j = 0; j < size(); j++) {
            System.out.print(peekN(j));
            System.out.print(‘ ‘);
        }
        System.out.println("");
    }
}

 

 2.InToPost类,存放的操作方法

package infix;

public class InToPost {
    private StackX stack;
    private String input;
    private String output="";
    
    public InToPost(String in){
        input = in;                        //输入的要分析的字符串
        int stackSize = input.length();
        stack = new StackX(stackSize);
    }
    /*
     * 将中缀表达式转化为后缀表达式
     * 如果读取的单个字符不是基础运算符,则将这个字符放入output中。output中的数据只会增加,不会变化
     */
    public String doTrans(){
        
        for (int i = 0; i < input.length(); i++) {
            char ch = input.charAt(i);   //从input中取出第i个字符
            stack.displayStack("For " + ch + " ");        //调用StackX中的方法来显示ch
            switch (ch) {
            case ‘+‘:
            case ‘-‘:
                gotOper(ch, 1);
                break;
            case ‘*‘:
            case ‘/‘:
                gotOper(ch, 2);
                break;
            case ‘(‘:
                stack.push(ch);
                break;
            case ‘)‘:
                gotParen(ch);
                break;
            default:
                output = output + ch;
                break;
            }
        }
        //将剩余的栈中元素全部出栈。出栈的顺序就代表了运算的顺序。
        while(!stack.isEmpty()){
            stack.displayStack("While ");
            output = output + stack.pop();
        }
        stack.displayStack("End  ");
        return output;
    }
    
    public void gotOper(char opThis, int prec1){
        while (!stack.isEmpty()) {       //循环将栈中的char类型出栈
            char opTop = stack.pop();
            if (opTop == ‘(‘) {            
                stack.push(opTop);        //将出栈的‘(’元素进栈
                break;
            }else {
                int prec2;
                //判断onTop的优先级
                if (opTop==‘+‘||opTop == ‘-‘) {        //设置加减的优先级为1
                    prec2 = 1;
                }else {                                //其他的优先级为2
                    prec2 = 2;
                }
                if (prec2 < prec1) {        //当传入的onThis的优先级prec1大于出栈的opTop的优先级
                    stack.push(opTop);      //将出栈的opTop进栈
                    break;
                }else {
                    output = output + opTop;    //如果出栈的opTop的算术优先级比opThis的大,则将其放到output中
                }
            }
        }
        stack.push(opThis);
    }
    public void gotParen(char ch){
        while (!stack.isEmpty()) {
            char chx = stack.pop();        //读取到‘(’,就出栈在‘(’和‘)’之间的所有元素
            if (chx == ‘(‘) {
                break;
            }else {
                output = output + chx;        //如果读到了‘)’,则将stack栈中的符号放入output中
            }
        }
    }
}

 

3.主类:

 

package infix;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
/*
 * 用栈来实现把一个中缀表达式,转化为一个后缀表达式
 */
public class InfixApp {
    public static void main(String[] args) throws IOException {
        String input,output;
        while(true){
            System.out.println("输入要运算式: ");
            System.out.flush();            
            input = getString();
            if (input.equals("")) {
                System.out.println("输入不要为空");
                break;
            }
            //创建InToPost对象
            InToPost theTrans = new InToPost(input);
            //调用doTrans方法
            output = theTrans.doTrans();
            System.out.println("转化后的运算式为: " + output + ‘\n‘);
        }
    }
    //用于读取输入流中的数据
    public static String getString() throws IOException{
        InputStreamReader in = new InputStreamReader(System.in);
        BufferedReader buffer = new BufferedReader(in);
        String s = buffer.readLine();
        return s;
    }
}

 运行结果:

输入要运算式: 
A*(B+C)-D/(E+F)
For A Stack (bottom-->top):
For * Stack (bottom-->top):
For ( Stack (bottom-->top):* 
For B Stack (bottom-->top):* ( 
For + Stack (bottom-->top):* ( 
For C Stack (bottom-->top):* ( + 
For ) Stack (bottom-->top):* ( + 
For - Stack (bottom-->top):* 
For D Stack (bottom-->top):- 
For / Stack (bottom-->top):- 
For ( Stack (bottom-->top):- / 
For E Stack (bottom-->top):- / ( 
For + Stack (bottom-->top):- / ( 
For F Stack (bottom-->top):- / ( + 
For ) Stack (bottom-->top):- / ( + 
While Stack (bottom-->top):- / 
While Stack (bottom-->top):- 
End  Stack (bottom-->top):
转化后的运算式为: ABC+*DEF+/-

输入要运算式:

 

栈 之 求后缀表达式

标签:

原文地址:http://www.cnblogs.com/mercuryli/p/5011151.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!