码迷,mamicode.com
首页 > 其他好文 > 详细

四则运算脚本解析计算

时间:2015-08-29 12:34:59      阅读:162      评论:0      收藏:0      [点我收藏+]

标签:

 

四则运算脚本解析计算

 

1.个位数的加减法运算

记住前一位的加号或减号运算符,使用加号或减号用运算符后面的数字改变累加值。

package yuki.arithmetic.script;

public class SingleDigitTest {

    public static void main(String[] args) {
        
        String s1 = "1+2+3+4+5+6+7+8+9";
        System.out.println(s1 + "=" + calculate(s1));
        
        String s2 = "1-2+3+4-5+6+7-8+9";
        System.out.println(s2 + "=" + calculate(s2));
    }

    private static int calculate(String s) {
        char[] cs = s.toCharArray();
        
        char oper = ‘+‘;
        int result = 0;
        for (int i = 0; i < cs.length; i++) {
            char c = cs[i];
            if(c == ‘+‘ || c == ‘-‘){
                oper = c;
            }else if(‘0‘ <= c && c <= ‘9‘) {
                int x = c - ‘0‘;
                switch (oper) {
                case ‘+‘:
                    result += x;
                    break;
                case ‘-‘:
                    result -= x;
                    break;
                }
            }
        }
        return result;
    }
}

 运行结果如下:

1+2+3+4+5+6+7+8+9=45
1-2+3+4-5+6+7-8+9=15

 

2.使用脚本引擎计算

java提供的脚本解析工具,如果解析的脚本是javascript脚本,实现类是RhinoScriptEngine。

package yuki.arithmetic.script;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

public class ScriptEngineTest {
    
    public static void main(String[] args) throws ScriptException {
        
        ScriptEngineManager engineManager = new ScriptEngineManager();
        ScriptEngine engine = engineManager.getEngineByName("javascript");
        
        String script = "1*2*3*4*5*6*7*8*9";
        Object result = engine.eval(script);
        System.out.println(script + " = " + result);
        System.out.println(script + " = " + 1*2*3*4*5*6*7*8*9);
    }
}

 运行结果如下:

1*2*3*4*5*6*7*8*9 = 362880.0
1*2*3*4*5*6*7*8*9 = 362880

 

3.带括号的四则运算

方便测试,上一行使用的是下文的四则运算解析,下一行使用的是javascript的脚本解析。

为了避免计算错误输入的脚本,所以在计算前做了去除空白字符,验证脚本是否输入规范。

从后往前的解析脚本,这与正常的计算顺序一致,因为使用了递归,都是把前面的结果算完了再和后面的结果操作。

如果是从前往后的解析脚本,途中出现减号,后面的算式作为一个括号中的整体参与减法,导致计算错误。

package yuki.arithmetic.script;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

public class ResolverDemo {

    public static void main(String[] args) throws ScriptException {
        
        String s1 = "1+2+(3+4)+(5+(6*7+8))+9";
        System.out.println(calculate(read(s1)));
        System.out.println(evalScript(s1));
        
        String s2 = "1+2+(3/4)+(5+(6*7+8/9))";
        System.out.println(calculate(read(s2)));
        System.out.println(evalScript(s2));
        
        String s3 = "((1+(2+(3/4))+(5+(6*78+9))))";
        System.out.println(calculate(read(s3)));
        System.out.println(evalScript(s3));
        
        String s4 = "1-(2-(3/4))+(5-(-6*7*8+9))";
        System.out.println(calculate(read(s4)));
        System.out.println(evalScript(s4));
        
        String s5 = "-12*3 + 4*56 - (7 + 8*9)/(2*3)";
        System.out.println(calculate(read(s5)));
        System.out.println(evalScript(s5));
    }
    
    public static Object evalScript(String script){
        ScriptEngine engine = new ScriptEngineManager().getEngineByName("javascript");
        try {
            return engine.eval(script);
        } catch (ScriptException e) {
            e.printStackTrace();
            return -1;
        }
    }
    
    public static String read(String s){
        s = s.replaceAll("\\s+", "");
        char[] cs = s.toCharArray();
        for (int i = 0, j = 1; j < cs.length; ++i, ++j)
            if((cs[i] == ‘+‘ || cs[i] == ‘-‘ || cs[i] == ‘*‘ || cs[i] ==‘/‘) && 
                    (cs[j] == ‘+‘ || cs[j] == ‘-‘ || cs[j] == ‘*‘ || cs[j] ==‘/‘))
                throw new RuntimeException("运算符相邻");
        int deep = 0;
        for (char c : cs) {
            if(c == ‘(‘)
                ++ deep;
            else if(c == ‘)‘)
                -- deep;
        }
        if(deep != 0)
            throw new RuntimeException("左右括号不等");
        return s;
    }
    
    public static double calculate(String s){
        char[] cs = s.toCharArray();
        if(cs.length == 0)
            return 0;
        
        int pos = -1;
        if((pos = plusPos(cs)) != -1){
            char oper = cs[pos];
            double left = calculate(s.substring(0, pos));
            double right = calculate(s.substring(pos + 1));
            if(oper == ‘+‘)
                return left + right;
            else if(oper == ‘-‘)
                return left - right;
        }else if((pos = timesPos(cs)) != -1){
            char oper = cs[pos];
            double left = calculate(s.substring(0, pos));
            double right = calculate(s.substring(pos + 1));
            if(oper == ‘*‘)
                return left * right;
            else if(oper == ‘/‘)
                return left / right;
        }else{
            if(cs[0] == ‘(‘ && cs[cs.length - 1] == ‘)‘){
                return calculate(s.substring(1, cs.length - 1));
            }else{
                int y = 0;
                for (char c : cs)
                    if(‘0‘ <= c && c <= ‘9‘)
                        y = y*10 + (c - ‘0‘);
                if(cs[0] == ‘-‘)
                    y *= -1;
                return y;
            }
        }
        
        return 0;
    }

    private static int plusPos(char[] cs) {
        int deep = 0;
        for (int i = cs.length - 1; i >= 0 ; --i) {
            char c = cs[i];
            switch (c) {
            case ‘(‘: 
                ++deep; 
                break;
            case ‘)‘: 
                --deep; 
                break;
            case ‘+‘:
            case ‘-‘:
                if(deep == 0)
                    return i;
                break;
            }
        }
        return -1;
    }
    
    private static int timesPos(char[] cs) {
        int deep = 0;
        for (int i = cs.length - 1; i >= 0 ; --i) {
            char c = cs[i];
            switch (c) {
            case ‘(‘: 
                ++deep; 
                break;
            case ‘)‘: 
                --deep; 
                break;
            case ‘*‘:
            case ‘/‘:
                if(deep == 0)
                    return i;
                break;
            }
        }
        return -1;
    }
    
}

 运行结果如下:

74.0
74.0
51.638888888888886
51.638888888888886
485.75
485.75
331.75
331.75
174.83333333333334
174.83333333333334

 

 

本文地址:http://www.cnblogs.com/kodoyang/p/Arithmetic_ScriptResolve_Calculate.html

雨木阳子
2015年8月29日

 

四则运算脚本解析计算

标签:

原文地址:http://www.cnblogs.com/kodoyang/p/Arithmetic_ScriptResolve_Calculate.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!