数据结构(四)java模拟计算器四则运算算法

来源:互联网 发布:苹果6s怎样打开数据 编辑:程序博客网 时间:2024/05/14 16:05

用java模拟解决计算器四则运算算法问题.

/** * 模拟实现计算器算法功能 */public class Calc {    public static void main(String[] args) {        String exp = "-3*-(3+6/6-3)*1";        System.out.println(calcBracket(exp));    }    /**     * 带括弧的四则运算     * @param exp 带括弧的表达式     * @return     */    public static double calcBracket(String exp){        //从最里面的括号开始运算,exp中最后出现的(最内层的括号        int lastIndexOf = exp.lastIndexOf('(');        //两种结果        if (lastIndexOf != -1) {            //有            //1.计算最内层括号表达式的值,找对应的右括号            int rightIndexOf = exp.indexOf(')', lastIndexOf);            double d = calc(exp.substring(lastIndexOf+1,rightIndexOf));            //2.把运算结果拼接            exp = exp.substring(0, lastIndexOf)+d+exp.substring(rightIndexOf+1);            return calcBracket(exp);        }else {            //没有            //没有括号的表达式            return calc(exp);        }    }    /**     *      * @param exp 不带括号的四则表达式     * @return     */    public static double calc(String exp){        //1.把表示负数的-号换成@号        exp = fu2At(exp);        //2.数字的分类        List<Double> numbers = splitNumExp(exp);        //3.运算符的分离        List<Character> ops = splitOpfromExp(exp);        //4.先乘除        for (int i = 0; i < ops.size(); i++) {            //判断,运算符是否是乘除            char op = ops.get(i);            //是,取出,运算            if (op == '*' || op == '/') {                //取出来,运算                ops.remove(i);//后面的数据往前顺序移动                //运算                //从数字容器中取出对应运算符的两个数字                double d1 = numbers.remove(i);                double d2 = numbers.remove(i);                if (op == '*') {                    d1 *= d2;                }else {                    d1 /= d2;                }                //把运算结果放入数字容器中i的位置                numbers.add(i, d1);//原来i位置(包括)后面的数据依次往后顺移                i--;            }        }        //5.后加减        while (!ops.isEmpty() ) {            char op = ops.remove(0);            double d1 = numbers.remove(0);            double d2 = numbers.remove(0);            //运算            if (op == '+') {                d1 += d2;            } else {                d1 -= d2;            }            //把运算结果插入到数字容器中0的位置            numbers.add(0, d1);        }        //6.容器中的第一个数据就是结果        return numbers.get(0);    }    /**     * 从表达式中分离表达式和运算符     * @param exp     * @return     */    private static List<Character> splitOpfromExp(String exp) {        List<Character> ops = new ArrayList<>();        StringTokenizer st = new StringTokenizer(exp, "1234567890.@");        while (st.hasMoreTokens()) {            char c = st.nextElement().toString().trim().charAt(0);            ops.add(c);        }        return ops;    }    /**     * 分离出数字     * @param exp     * @return     */    private static List<Double> splitNumExp(String exp) {        List<Double> numbers = new ArrayList<>();        StringTokenizer st = new StringTokenizer(exp, "+-*/");        while (st.hasMoreTokens()) {            String numStr = st.nextElement().toString().trim();            if (numStr.charAt(0) == '@') {                numStr = "-" + numStr.substring(1);            }            numbers.add(Double.parseDouble(numStr));        }        return numbers;    }    /**     * 把-号换成@号     * @param exp     * @return     */    private static String fu2At(String exp) {        for (int i = 0; i < exp.length(); i++) {            char c = exp.charAt(i);            if (c == '-') {                //判断是否是负数                if (i == 0) {                    //第一个位置肯定是负数                    exp = "@"+exp.substring(1);                }else {                    //不是第一个位置                    //判断前一个位置是否是运算符                    char cprev = exp.charAt(i - 1);                    if (cprev == '+' || cprev == '-' || cprev == '*' || cprev == '/') {                        exp = exp.substring(0, i)+"@"+exp.substring(i+1);                    }                }            }        }        return exp;    }}
0 0
原创粉丝点击