Java实现表达式计算(中缀表达式向逆波兰式的转换)

定义:

中缀表达式:

我们平时写的数学表达式一般为中缀表达式,如“5+2*(3*(3-1*2+1))”,直接拿中缀表达式直接让计算机计算表达式的结果并不能做到。

后缀表达式:

把中缀表达表达式“5+2*(3*(3-12+1))”转化“523312-1+**+”这样的形式,就是后缀表达式。这种记法叫做后缀(postfix)或逆波兰(reverse Polish)记法。计算这个问题最容易的方法就是使用一个栈。

具体实现:

(1)方法概述:

1.从左到右进行遍历。
2.运算数,直接输出。
3.左括号,直接压入堆栈,括号是最高优先级,无需比较,入栈后优先级降到最低,确保其他符号正常入栈
4.右括号,(意味着括号已结束)不断弹出栈顶运算符并输出直到遇到左括号(弹出但不输出)。
5.运算符,将该运算符与栈顶运算符进行比较
如果优先级高于栈顶运算符则压入堆栈(该部分运算还不能进行)。
如果优先级低于等于栈顶运算符则将栈顶运算符弹出并输出,然后比较新的栈顶运算符。
低于弹出意味着前面部分可以运算,先输出的一定是高优先级运算符,等于弹出是因为同等优先级,从左到右运算。
直到优先级大于栈顶运算符或者栈空,再将该运算符入栈。
6.如果对象处理完毕,则按顺序弹出并输出栈中所有运算符。

(2)转换举例:

输入:(2*(9+6/3-5)+4)

操作说明输出
读取(把(直接压入栈(----
读取2把操作数直接输出(2
读取*把*直接压入栈(*2
读取(把(直接压入栈(*(2
读取9把操作数直接输出(*(29
读取+把+直接压入栈(*(+29
读取6把操作数直接输出(*(+296
读取/栈顶元素为+,优先级低于/,把操作符压入栈中(*(+/296
读取3把操作数直接输出(*(+/2963
读取-栈顶元素为/,优先级高于-,以此弹出/和+,到 ( 停止,把操作符压入栈中(*(-2963/+
读取5把操作数直接输出(*(-2963/+5
读取)从栈中弹出-到输出,遇到第一个 ( 停止,把 ( 弹出栈(*2963/+5-
读取+栈顶元素为*,优先级高于+,以此弹出 ,到 ( 停止,把操作符压入栈中(+2963/+5-*
读取4把操作数直接输出(+2963/+5-*4
读取)从栈中弹出+到输出,遇到第一个 ( 停止,把 ( 弹出栈2963/+5-*4+
(3)代码实现
import java.util.Stack; 
 
 
public class Main {
 
    static Stack<Character> op = new Stack<>();
 
    public static Float getv(char op, Float f1, Float f2){
        if(op == '+') return f2 + f1;
        else if(op == '-') return f2 - f1;
        else if(op  == '*') return f2 * f1;
        else if(op == '/') return f2 / f1;
        else return Float.valueOf(-0);
    }
    public static float calrp(String rp){
        Stack<Float> v = new Stack<>();
        char[] arr = rp.toCharArray();
        int len = arr.length;
        for(int i = 0; i < len; i++){
            Character ch = arr[i];
 
            if(ch >= '0' && ch <= '9') {
            v.push(Float.valueOf(ch - '0'));
            } else v.push(getv(ch, v.pop(), v.pop()));
        }
        return v.pop();
    }
 
    public static String getrp(String s){
         char[] arr = s.toCharArray();
         int len = arr.length;
         String out = "";
 
         for(int i = 0; i < len; i++){
             char ch = arr[i];
             if(ch == ' ') {
             	continue;
             }

             if(ch >= '0' && ch <= '9') {
                 out+=ch;
                 continue;
             }
 
             if(ch == '(') {
             op.push(ch);
             }
             if(ch == '+' || ch == '-'){
                 while(!op.empty() && (op.peek() != '(')) 
                     out+=op.pop();
                 op.push(ch);
                 continue;
             }
             if(ch == '*' || ch == '/'){
                 while(!op.empty() && (op.peek() == '*' || op.peek() == '/')) 
                     out+=op.pop();
                 op.push(ch);
                 continue;
             }
             if(ch == ')'){
                 while(!op.empty() && op.peek() != '(') 
                     out += op.pop();
                 op.pop();
                 continue;
             }
         }
         while(!op.empty()) out += op.pop();
         return out;
    }
}
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值