栈的应用:后缀表达式

目录

表达式的转换:

运算符优先级:

 代码:

class StackCalculator的PostFix方法

ArrayStack类模拟堆栈:先进后出




表达式的转换:

        表达式一般有中级表达式、后缀表达式和前缀表达式3种表示形式,通常我们使用中缀表示,但是中缀表达式在计算机中存储计算时,比较麻烦,所以计算机内存储表达式时,一般采用后缀或前缀表示较多。
        一个表达式通常由操作数、运算符及分隔符所构成。一般我们习惯使用中缀描述法,也就是将运算符放在操作数中间,例如:a+b*c
        由于运算符有优先级,所以在计算机内部使用中缀描述是非常不方便的,特别是带有括号时更麻烦。为方便处理起见,一般需要将中级的表达式利用堆栈转换成为计算机比较容易识别(没有括号)的前缀或后缀表达式,这样在扫描表达式时,只要按照运算符直接计算即可。例如:

                              +a*bc 前缀表达式
                              abc*+ 后缀表达式

                       中缀表达式 9+(3-1)×3+10÷2

                       后缀表达式 9 3 1-3*+10 2/+

中缀表达式转后缀表达式 转换原则:
* 1 从左至右读取一个表达式。
* 2 若读取的是操作数,则直接输出。
* 3 若读取的是运算符,分3种情况:
*   (1)左括号“(”直接存入堆栈;
*   (2)右括号“)”输出堆栈中的运算符,直到取出左括号为止;
*   (3)非括号运算符,优先级比栈顶高的直接存入堆栈,比栈顶低或相等则输出堆栈中的运算符。
* 4 表达式读取完成后,依次取出堆栈中的运算符,直到堆栈为空。

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBASm9ueUx1THXkuLY=,size_20,color_FFFFFF,t_70,g_se,x_16

运算符优先级:

假设栈顶元素的运算符是θ1,新读到的元素是θ2

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBASm9ueUx1THXkuLY=,size_20,color_FFFFFF,t_70,g_se,x_16

 代码:

public class StackCalculator {        
    public static void main(String[] args) {            
        Scanner in = new Scanner(System.in);        
        String inorder = in.nextLine();        //读取表达式并转换,直到退出        
        while (!inorder.equals("exits")) {            
            String newOrder = PostFix(inorder); //转换表达式            
            System.out.println(newOrder);            
            inorder = in.nextLine();        
        }    
    }
输入:9+(3-1)*3+10/2输出:931-3*+102/+

class StackCalculator的PostFix方法

    public static String PostFix(String infix){      
        StringBuilder postfix = new StringBuilder();
        int position = 0;
        ArrayStack operator = new ArrayStack(); //运算符堆栈

        //从左至右中缀表达式遍历字符串
        while (position < infix.length()){
            char cur = infix.charAt(position++); //保存当前字符
            //1.数字直接输出
            if (!operator.isOperator(cur)) {
                postfix.append(cur);
                continue;
            }
            //2.左括号直接入栈
            if (operator.top == -1 || cur=='(') {
                operator.push(cur);
            }

            /*3.若是右括号,取出运算符直到取出'(',若无'('配对则抛出异常
                若是运算符‘+’或‘-’(优先级只比'('高):
                1.栈内有'(',则取出'('上面的运算符,将当前运算符添加到栈顶;
                2.否则全部出栈,并将当前运算符添加到栈顶。
             */
            else if (cur == ')' || operator.priority(cur) <= operator.priority(operator.topElement())){
                boolean takeOut = false;

                while(operator.top != -1) {
                    if (operator.topElement() == '(') {
                        operator.pop2();
                        takeOut = true;
                        break;
                    }
                    postfix.append(operator.pop2());
                }
                if (operator.top == -1)
                    if (cur == ')' && !takeOut)
                        throw new RuntimeException("Error:No '(' in th left of ')'");
                    else operator.push(cur);
            }

            //运算符* /入栈
            else
                operator.push(cur);
        }
//字符串遍历完后,将堆栈中的运算符全部弹出
        while (operator.top!=-1)
            postfix.append(operator.pop2());
        return postfix.toString();
    }
}

ArrayStack类模拟堆栈:先进后出

class ArrayStack{
    char[] stack ;
    public int top;
    private final int capacity = 10;

    ArrayStack(){
        this.top = -1;
        this.stack = new char[capacity];
    }

    public boolean push(char element){
        if (top == capacity-1) {
            System.out.println("Stack overFlow");
            return false;
        }
        stack[++top] = element;
        return true;
    }

    public char pop2(){
        char topElement;
        char[] l = this.stack;
        if (top == -1){
            System.out.println("Empty Stack");
            return '\u0000';
        }
        topElement = l[top];
        l[top--] = '\u0000';
        return topElement;
    }

    public char topElement() throws RuntimeException {
        if (top == -1) {
            return '\u0000';
        }
        else
            return this.stack[top];
    }

    public boolean isOperator(char operator){
        return operator == '+' || operator == '-' ||
                operator == '*' || operator == '/' ||
                operator == '(' || operator == ')';
    }

    public int priority(char operator) {
        switch (operator) {
            case '+':
            case '-':
                return 1;
            case '*':
            case '/':
            //case '(':
                return 2;
        }
        return 0;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值