解析算数表达式

步骤主要是两部:
1.将算数表达式转换为后缀表达式
2.求后缀表达式的值
在之前首先要明确什么是后缀表达式:在我们写表达式时一般把操作符(+,-,,/)放在两个字符之间,例如A+B,A/B,这个被称为中缀表达式,而后缀表达式是将操作符放在字符后面,于是变成了AB+,AB/。如下表所示所示为典型的变换
中
首先解决第一个问题:如何将中缀表达式转化为后缀表达式?
首先解析3+4
5:
在这里插入图片描述
解析3*(4+5)
在这里插入图片描述
由上图可以看出,在读中缀表达式的时候既要向前读又要向后读,这样会比较麻烦,将中缀表达式转化为后缀表达式是一个不错的方法。
转化过程:
A+B-C
在这里插入图片描述
A+BC在这里插入图片描述
在这里插入图片描述
A
(B+C)
在这里插入图片描述
A+B*(C-D)
在这里插入图片描述
由上图可以看出将数据存在ABCD依次取出,将中间遇到的操作符暂时放入栈中,每当遇到优先级更高的操作符时则继续压栈,当下一个操作符优先级比栈顶的低时则出栈加入后缀表达式中。

package com.stackDemo;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Stack;

public class LastSymbol {
    static Stack<Character> sta = new Stack<>();
    static String output="";
    public static void main(String[] args) throws IOException {
        String input,output;
        input = getString();
        output = mediumToLast(input);
        System.out.println(output);
    }
    public static String mediumToLast(String input){
        for(int i = 0; i < input.length(); i++){
            char ch = input.charAt(i);
            switch(ch){
                case '-':
                case '+':
                    doOper(ch,1);
                    break;
                case '/':
                case '*':
                    doOper(ch,2);
                    break;
                case '(':
                    sta.push(ch);
                    break;
                case ')':
                    gotParOper();
                    break;
                default:output += ch;
                break;
            }
        }
        while(!sta.empty()){
            output += sta.pop();
        }
        return output;
    }
    public static void doOper(char ch,int per){
        int peri = 0;
        while( !sta.isEmpty()){
            if(ch == '(') {
                sta.push(ch);
                break;
            }
            char chp = sta.pop();
            if(chp == '+' || chp == '-')peri = 1;
            if(chp == '*' || chp == '/')peri = 2;
            if(per <= peri)
                output += chp;
            else {
                sta.push(chp);
                break;
            }
        }
        sta.push(ch);
    }
    public static void gotParOper(){
        while(!sta.empty()){
            char ch = sta.pop();
            if(ch == '('){
                break;
            }
            else{
                output += ch;
            }
        }
    }
    public static String getString() throws IOException {
        InputStreamReader isr = new InputStreamReader(System.in);
        BufferedReader br = new BufferedReader(isr);
        String s = br.readLine();
        return s;
    }
}

输入输出效果:
在这里插入图片描述
2,得到后缀表达式后,我们就需要求解了,求解方式如下所示:
在这里插入图片描述
全部退栈后得到的结果就是表达式结果。

package com.stackDemo;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Stack;

public class LastSymbol {
    static Stack<Character> sta = new Stack<>();
    static String output="";
    public static void main(String[] args) throws IOException {
        String input,output;
        input = getString();
        output = mediumToLast(input);
        System.out.println(output);
        Stack<Integer> lastsym = new Stack<>();
        for(int i = 0; i < output.length(); i++){
            char ch = output.charAt(i);
            if(ch == '+' ||output.charAt(i) == '-' ||ch == '*' ||ch == '/' ){
                int x = lastsym.pop();
                int y = lastsym.pop();
                if(ch == '+') y = y + x;
                if(ch == '-') y -=  x;
                if(ch == '*') y = y*x;
                if(ch == '/') y = y/x;
                lastsym.push(y);
            }else  {
                lastsym.push((int)output.charAt(i)-'0');
            }
        }
        System.out.println(lastsym.pop());
    }
    public static String mediumToLast(String input){
        for(int i = 0; i < input.length(); i++){
            char ch = input.charAt(i);
            switch(ch){
                case '-':
                case '+':
                    doOper(ch,1);
                    break;
                case '/':
                case '*':
                    doOper(ch,2);
                    break;
                case '(':
                    sta.push(ch);
                    break;
                case ')':
                    gotParOper();
                    break;
                default:output += ch;
                break;
            }
        }
        while(!sta.empty()){
            output += sta.pop();
        }
        return output;
    }
    public static void doOper(char ch,int per){
        int peri = 0;
        while( !sta.isEmpty()){
            if(ch == '(') {
                sta.push(ch);
                break;
            }
            char chp = sta.pop();
            if(chp == '+' || chp == '-')peri = 1;
            if(chp == '*' || chp == '/')peri = 2;
            if(per <= peri)
                output += chp;
            else {
                sta.push(chp);
                break;
            }
        }
        sta.push(ch);
    }
    public static void gotParOper(){
        while(!sta.empty()){
            char ch = sta.pop();
            if(ch == '('){
                break;
            }
            else{
                output += ch;
            }
        }
    }
    public static String getString() throws IOException {
        InputStreamReader isr = new InputStreamReader(System.in);
        BufferedReader br = new BufferedReader(isr);
        String s = br.readLine();
        return s;
    }
}

在这里插入图片描述
如此,完成了最后的操作。
总结一下:充分利用了栈的后进先出的特点,一方面通过栈来保存操作符,完成中缀表达式转换成后缀表达式;另一方面,通过栈来暂存数值,每次遇到符号时取出两个值进行操作。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值