转载

四则运算脚本解析计算

四则运算脚本解析计算

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日

正文到此结束
Loading...