四则运算脚本解析计算

四则运算脚本解析计算

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日

时间: 2024-08-01 18:21:28

四则运算脚本解析计算的相关文章

android init进程分析 init脚本解析和处理

(懒人近期想起我还有csdn好久没打理了.这个android init躺在我的草稿箱中快5年了.略微改改发出来吧) RC文件格式 rc文件是linux中常见的启动载入阶段运行的文件.rc是run commands的缩写.基本上能够理解为在启动阶段运行的一些列命令.android init进程启动时,也会运行此启动脚本文件,init.rc.init.rc的写法稍有点复杂,具体可參考 /system/core/init下的readme文件.脚本基本组成是由四类,为: commands: 命令 act

shell脚本解析5----循环语句

一.for循环 for var in [ list ] do #code block done $var是循环控制变量,[list]是var需要遍历的一个集合,do/done对包含了循环体.如果do和for被写在同一行,必须在do前面加上“;”,如:for $var in [list]; do 例如: #!/bin/bash for day in Sun Mon Tue Wed Thu Fri Sat do echo $day done 执行结果: 如果列表被包含在一对括号中,则被认为是一个元素

shell脚本解析6----case语句

BASH中的case结构,可以用于进行多项分支. case "$var" in condition1) ;; condition2) ;; *) default statments;; esac 例如: #!/bin/bash echo "Hit a key, then hit return" read Keypress case "$Keypress" in [A-Z]) echo "Uppercase letter";;

shell脚本解析4----分支语句(if)

一.条件语句 1. if [expression] then #code block fi 2. if [expression] then #code block else #code block fi 3. if [expression] then #code block else if [expression]    #该处可以替换成elif [expression] then #code block else #code block fi fi 二.条件语句中常用的比较 比较操作    

shell脚本解析9(练习3)------倒序输出

#!/bin/bash #提示用户输入 echo -n "Please enter number" read n #读入输入的值放到变量n中 sd=0 rev="" on=$n #将变量n的值保存到变量on中,方便以后用到 echo "You put number is $n" while [ $n -gt 0 ] do sd=$(($n % 10)) #求余 n =$(($n/10))     #去掉当前的最后一位数后,剩下的数 rev=&qu

shell脚本解析8(练习2)-----文件个数统计

#!/bin/bash counter=0 #变量files遍历一遍当前文件夹 for files in * do #判断files是否为文件,如果是,counter变量值加1,再赋值给自己. if [ -f "$files" ] then counter=`expr $counter + 1` fi done echo "There are $counter files in `pwd`" 执行结果: 注意:表达式counter=`expr $counter +

shell脚本解析10(练习4)------监视文件

#!/bin/bash  #判断命令行是否代带有两个文件名的参数 if [ "$1" = "" ] || [ "$2" = "" ] then      echo "Please enter file name"      exit 1 fi  #判断目标文件是否存在 if [ -e $2 ] then   echo "The file already exists"   until [

shell脚本解析3-----局部变量与函数

#!/bin/bash hello="var1" echo $hello function func1                             #定义函数func1 { local hello="var2"                    #定义内部变量hello echo $hello } func1                                          #进行函数调用 echo $hello 执行结果: 总结:局

shell脚本解析2----变量

一.一般变量 #/bin/sh num=2 echo "this is the ${num}nd"     #shell脚本语言的变量如果紧连字母时,需要加上“{}”进行区分. 输出结果: 二.系统变量 $#:传入脚本的命令行参数个数 $*:所有命令行参数值,在各个参数值之间留有空格 $0:命令本身(shell文件名) $1:第一个命令行参数 $2:第二个命令行参数 例如: #/bin/sh echo "number of vars:"$# echo "v