java数学表达式计算算法

6 篇文章 0 订阅

数学表达式计算算法,为了方便直接将数值类型格式化为了double,看到的朋友帮忙测测

计算规则,先%,后* /再+ -先括号内在括号外先左后右,只是写了个算法的思路,有些细节没有处理,有时间补上。

 

此算法采用操作符进栈比较优先级的策略决定是否计算栈顶操作符的表达式。记得大学时写编译器的时候我用的是循环检测栈内最内层的括号,找到后按照 % * / + -的优先级顺序进行脱括号计算,知道没有括号后在进行一轮的循环计算。此算法代码的实现上和逻辑上较为简单,本文的算法是根据数据结构中给的算法思路整理的java代码算法。

 

/**author:a276202460*CreateDate:2009-11-17**/
package com.rich.expression;
import java.util.Stack;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ExpressionOptr {
    private static final String optrflag = "(#+-#*/#%)";
    private static final Pattern errorpattern = Pattern.compile("([^0-9//+//-//*///(//)//. %]|" + "[^0-9]{1,}//.[^0-9]{1,}|" + "^//.|" + "//.$|" + "//([^0-9//( ]|" + "[^0-9//) ]//)|" + "[^//+//-//*///(% ]//(|" + "//)[^//+//-//*///) %])");
    private static Matcher m;

    public static void main(String[] s) {
        String expression = " 3.2 * ( 5.3+3.4-5.5 / 4 ) + 9 -4 %(5-2) ";
        System.out.println(getResult(expression));
        System.out.println(3.2 * (5.3 + 3.4 - 5.5 / 4) + 9 - 4 % (5 - 2));
    }

    public static double getResult(String expression) {
        String validatestr = validateExpression(expression);
        if (validatestr != null) {
            throw new RuntimeException("Error with unexpected char:" + validatestr);
        }
        expression = expression.trim();
        expression = expression.replaceAll("//+", " + ").replaceAll("//-", " - ").replaceAll("//*", " * ").replaceAll("/", " / ").replaceAll("%", " % ").replaceAll("//(", " ( ").replaceAll("//)", " ) ").replaceAll(" +", " ").replaceAll("^ ", "").replaceAll(" $", "");
        Stack valuestack = new Stack();
        Stack optrstack = new Stack();
        String[] expchars = expression.split(" +");
        int startindex = 0;
        String ep;
        String top;
        while (startindex < expchars.length) {
            ep = expchars[startindex];
            startindex++;
            if (optrflag.indexOf(ep) == -1) {
                valuestack.push(ep);
            } else {
                if (optrstack.isEmpty()) {
                    optrstack.push(ep);
                    continue;
                }
                top = optrstack.pop().toString();
                int rs = comparepri(top, ep);
                if (rs == 0) {
                    continue;
                } else if (rs < 0) {
                    optrstack.push(top);
                    optrstack.push(ep);
                } else {
                    startindex--;
                    double b = Double.parseDouble(valuestack.pop().toString());
                    double a = Double.parseDouble(valuestack.pop().toString());
                    valuestack.push("" + getresult(a, b, top));
                }
            }
        }
        while (!optrstack.isEmpty()) {
            double b = Double.parseDouble(valuestack.pop().toString());
            double a = Double.parseDouble(valuestack.pop().toString());
            valuestack.push("" + getresult(a, b, optrstack.pop().toString()));
        }
        return Double.parseDouble(valuestack.pop().toString());
    }

    public static String validateExpression(String expression) {
        expression = expression.replaceAll(" +", " ");
        m = errorpattern.matcher(expression);
        if (m.find()) {
            return m.group(1);
        }
        m = errorpattern.matcher(expression.trim());
        if (m.find()) {
            return m.group(1);
        }
        return null;
    }

    private static int comparepri(String top, String insert) {
        int i = optrflag.indexOf(top);
        int j = optrflag.indexOf(insert);
        if (i < 0 || i == 1 || i == 4 || i == 7 || j < 0 || j == 1 || j == 4 || j == 7) {
            throw new RuntimeException("Error");
        }
        int distance = j - i;
        if (distance == -9) {
            throw new RuntimeException("Error");
        }
        if (distance == 9) {
            return 0;
        } else if (i == j && i != 0) {
            return 1;
        } else if (i == j && i == 0) {
            return -1;
        } else if (j == 9) {
            return 1;
        } else if (j == 0) {
            return -1;
        } else if (j - i <= 1) {
            return 1;
        } else {
            return -1;
        }
    }

    public static double getresult(double a, double b, String operator) {
        char operat = operator.toCharArray()[0];
        switch (operat) {
            case '%':
                return getmod(a, b);
            case '+':
                return getsum(a, b);
            case '-':
                return getgap(a, b);
            case '*':
                return getproduct(a, b);
            case '/':
                return getquotient(a, b);
            default: {
                throw new RuntimeException("Error");
            }
        }
    }

    public static double getsum(double a, double b) {
        return a + b;
    }

    public static double getgap(double a, double b) {
        return a - b;
    }

    public static double getproduct(double a, double b) {
        return a * b;
    }

    public static double getquotient(double a, double b) {
        if (b == 0) {
            throw new RuntimeException("Error with / 0");
        }
        return a / b;
    }

    public static double getmod(double a, double b) {
        if (b == 0) {
            throw new RuntimeException("Error with % 0");
        }
        return a % b;
    }
}

 

 

 学生时代的算法现在用到了自己的产品中,发现各方面表现还不错,特回来备注留念下当时的烂代码。

一洽在线客服软件

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值