欢迎访问悦橙教程(wld5.com),关注java教程。悦橙教程  java问答|  每日更新
页面导航 : > > 文章正文

java处理数学表达式,java数学表达式,[Java]代码pack

来源: javaer 分享于  点击 6217 次 点评:168

java处理数学表达式,java数学表达式,[Java]代码pack


[Java]代码

package interesting;    public class Calculator{        public static final int NULL_MARK = 0;          // 标记为空或者结束符        public static final int SEPARATION_MARK = 1;    // 标记为分隔符        public static final int VAR_MARK = 2;           // 标记为变量        public static final int NUM_MARK = 3;           // 标记为数字        public static final int GRAMMAR_Exception = 0;  // 语法错误        public static final int UNEND_Exception = 1;        // 括号没有结束错误        public static final int NULLEXP_Exception = 2;      // 表达式为空错误        public static final int BYZERO_Exception = 3;       // 被0除错误        public static final String[] MESSAGES_Exception = { "语法错误", "大括号没有成对错误",                "表达式为空错误", "被0除错误" };        public static final String END = "\0";          // 表达式的结束标记        private String expre;                   // 表达式字符串        private int position;                       // 求值器当前指针在表达式中的位置        private String current;                     // 求值器当前处理的标记        private int currentType;                    // 求值器当前处理标记的类型        private double varArray[] = new double[26];     // 变量的数组        /** 求值一个表达式,返回表达式的值。 */        public double analysis(String str) throws Exception {            double result;            this.expre = str;            this.position = 0;            // 获取第一个标记            this.getMark();            if (this.current.equals(END)) {            // 没有表达式异常                this.proce_Exception(NULLEXP_Exception);            }            result = this.proce_Evalua();           // 处理赋值语句            // 处理完赋值语句,应该就是表达式结束符,如果不是,则返回异常            if (!this.current.equals(END)) {                this.proce_Exception(GRAMMAR_Exception);            }            return result;        }        private double proce_Evalua() throws Exception {            double result;                  // 结果            int var_Index;                  // 变量下标            String oldMark;                 // 旧标记            int oldMarkType;                // 旧标记的类型                // 如果标记类型是变量            if (this.currentType == VAR_MARK) {                // 保存当前标记                oldMark = new String(this.current);                oldMarkType = this.currentType;                // 取得变量的索引,本求值器只支持一个字目的变量,                // 如果用户的变量字母长度大于1,则取第一个字母当作变量                var_Index = Character.toUpperCase(this.current.charAt(0)) - 'A';                // 获得下一个标记                this.getMark();                // 如果当前标记不是等号=                if (!this.current.equals("=")) {    // 判断当前表达式是否是赋值运算                    this.rollBack();            // 回滚                    // 不是一个赋值语句,将标记恢复到上一个标记                    this.current = new String(oldMark);                    this.currentType = oldMarkType;                } else {                    // 如果当前标记是等号=,即给变量赋值,形式如a = 3 + 5;                    // 则计算等号后面表达式的值,然后将得到的值赋给变量                    this.getMark();                    // 因为加减法的优先级最低,所以计算加减法表达式。                    result = this.arith_AddExpre();                    // 将表达式的值赋给变量,并存在实例变量vars中。                    this.varArray[var_Index] = result;                    return result;                }            }            return this.arith_AddExpre();   // 调用arith_AddExpre方法,进行加减法计算表达式的值。        }        private double arith_AddExpre() throws Exception {            char op;                    // 操作符            double result;              // 结果            double partialResult;       // 当前子表达式的结果            result = this.arith_MulExpre();     // 调用arith_MulExpre方法获取当前子表达式的值                    // 当前标记的第一个字母是加减号,则继续进行加减法运算。            while ((op = this.current.charAt(0)) == '+' || op == '-') {                this.getMark(); // 取下一个标记                partialResult = this.arith_MulExpre();  // 调用arith_MulExpre方法获取当前子表达式的值                switch (op) {                case '-':                    // 如果是减法,则用已处理的子表达式的值减去当前子表达式的值                    result = result - partialResult;                    break;                case '+':                    // 如果是加法,用已处理的子表达式的值加上当前子表达式的值                    result = result + partialResult;                    break;                }            }            return result;        }        private double arith_MulExpre() throws Exception {            char op;                    // 运算符            double result;              // 表达式结果            double currentResult;       // 子表达式的结果            // 用指数运算计算当前子表达式的值            result = this.indexExpre();            // 如果当前标记的第一个字母是乘、除或者取模运算符,则继续进行乘除法运算。            while ((op = this.current.charAt(0)) == '*' || op == '/' || op == '%') {                this.getMark();             // 取下一个标记            // 用指数运算计算当前子表达式的值                currentResult = this.indexExpre();                switch (op) {                case '*':                    // 如果是乘法,则用已处理子表达式的值乘以当前子表达式的值                    result = result * currentResult;                    break;                case '/':                    // 如果是除法,判断当前子表达式的值是否为0,如果为0,则抛出被0除异常                    // 除数不能为0                    if (currentResult == 0.0) {                        this.proce_Exception(BYZERO_Exception);                    }                    // 除数不为0,则进行除法运算                    result = result / currentResult;                    break;                case '%':                    // 如果是取模运算,也要判断当前子表达式的值是否为0                    // 如果为0,则抛出被0除异常                    if (currentResult == 0.0) {                        this.proce_Exception(BYZERO_Exception);                    }                    // 进行取模运算                    result = result % currentResult;                    break;                }            }            return result;        }        private double unaryOperator() throws Exception {            double result;  // 表达式结果            String op;  // 运算符            op = "";            // 如果当前标记类型为分隔符,而且分隔符的值等于+或者-。            if ((this.currentType == SEPARATION_MARK) && this.current.equals("+")                    || this.current.equals("-")) {                op = this.current;                this.getMark();            }            // 用括号运算计算当前子表达式的值            result = this.parenthesis();            if (op.equals("-")) {            // 如果操作符为-,则表示负数,将子表达式的值变为负数                result = -result;            }            return result;        }        private double parenthesis() throws Exception {            double result;                  // 表达式结果            if (this.current.equals("(")) {     // 如果当前标记为左括号,则表示是一个括号运算                this.getMark();                 // 取下一个标记                result = this.arith_AddExpre(); // 调用arith_AddExpre方法                // 判断括圆括号是否匹配,如果当前标记不等于右括号,抛出括号不匹配异常                if (!this.current.equals(")")) {                     this.proce_Exception(UNEND_Exception);                }                this.getMark();                 // 否则取下一个标记            } else {                // 如果标记不是左括号,表示不是一个括号运算,则调用varNumber方法                result = this.varNumber();            }            return result;        }        private double varNumber() throws Exception {            double result = 0.0;    // 结果            switch (this.currentType) {            case NUM_MARK:                // 如果当前标记类型为数字                try {                // 将数字的字符串转换成数字值                    result = Double.parseDouble(this.current);                } catch (NumberFormatException exc) {                    this.proce_Exception(GRAMMAR_Exception);                }                this.getMark();     // 取下一个标记                break;            case VAR_MARK:                // 如果当前标记类型是变量,则取变量的值                result = this.seekVar(current);                this.getMark();                break;            default:                this.proce_Exception(GRAMMAR_Exception);                break;            }            return result;        }        private double seekVar(String vname) throws Exception {            // 判断是否有语法异常发生,如果变量的第一个字符不是字母,则抛出语法异常            if (!Character.isLetter(vname.charAt(0))) {                 proce_Exception(GRAMMAR_Exception);                return 0.0;            }            // 从实例变量数组varArray中取出该变量的值            return varArray[Character.toUpperCase(vname.charAt(0)) - 'A'];        }        private double indexExpre() throws Exception {            double result;              // 表达式结果            double currentResult;       // 子表达式的值            double ex;              // 指数的底数            int t;                  // 指数的幂            result = this.unaryOperator();  // 调用unaryOperator方法,获取当前表达式中的底数值            if (this.current.equals("^")) { // 如果当前标记为"^"运算符,则为指数计算                // 获取下一个标记,即获取指数的幂                this.getMark();                currentResult = this.indexExpre();                ex = result;                if (currentResult == 0.0) {                // 如果指数的幂为0,则指数的值为1                    result = 1.0;                } else {                    // 否则,指数的值为个数为指数幂的底数相乘的结果。                    for (t = (int) currentResult - 1; t > 0; t--) {                        result = result * ex;                    }                }            }            return result;        }        private void rollBack() {            if (this.current == END) {                return;            }            // 求值器当前指针往前移动            for (int i = 0; i < this.current.length(); i++) {                this.position--;            }        }        private void proce_Exception(int errorType) throws Exception {            // 遇到异常情况时,根据错误类型,取得异常提示信息,将提示信息封装在异常中抛出            throw new Exception(MESSAGES_Exception[errorType]);        }        private void getMark() {            // 设置初始值            this.currentType = NULL_MARK;            this.current = "";            // 判断表达式是否结束,如果求值器当前指针等于字符串的长度则表示表达式已经结束            if (this.position == this.expre.length()) {                 this.current = END;             // 如果表达式已经结束,则设置当前标记的置为END。                return;            }            while (this.position < this.expre.length()  // 当遇到表达式中的空白符则跳过                    && Character.isWhitespace(this.expre.charAt(this.position))) {                ++this.position;            }            if (this.position == this.expre.length()) { // 判断当前表达式是否结束                this.current = END;                return;            }            char currentChar = this.expre.charAt(this.position); // 取得求值器当前指针指向的字符            if (isSepara(currentChar)) {            // 如果当前字符是一个分隔符,则认为这是一个分隔符标记,                this.current += currentChar;        // 给当前标记和标记类型赋值,并将指针后移                this.position++;                this.currentType = SEPARATION_MARK;            } else if (Character.isLetter(currentChar)) {// 判断当前字符是否是一个字母                while (!isSepara(currentChar)) {    // 依次求值该变量的组成部分,直到遇到一个分隔符为止                    this.current += currentChar;                    this.position++;                    if (this.position >= this.expre.length()) {                        break;                    } else {                        currentChar = this.expre.charAt(this.position);                    }                }                this.currentType = VAR_MARK;    // 设置标记类型为变量            } else if (Character.isDigit(currentChar)) {    // 判断当前字符是否是一个数字                while (!isSepara(currentChar)) {    // 依次求值该数字的组成部分,直到遇到一个分隔符为止                    this.current += currentChar;                    this.position++;                    if (this.position >= this.expre.length()) {                        break;                    } else {                        currentChar = this.expre.charAt(this.position);                    }                }                this.currentType = NUM_MARK;    // 设置标记类型为数字            } else {                // 如果是无法识别的字符,则设置表达式结束                this.current = END;                return;            }        }        private boolean isSepara(char c) {            if ((" +-/*%^=()".indexOf(c) != -1))                return true;            return false;        }        public static void main(String[] args) throws Exception {            Calculator calculator = new Calculator();            double a = 15.0, b = 7.0;            String express1 = "a = 15.0";            System.out.println("表达式1:(\"a = 15.0\") = " + calculator.analysis(express1));            String express2 = "b = 7.0";            System.out.println("表达式2:(\"b = 7.0\") = " + calculator.analysis(express2));            String express3 = "(a+b) * (a-b)";            System.out.println("表达式3:(\"(" + a + "+" + b + ") * (" + a + "-" + b                    + ")\") = " + calculator.analysis(express3));            String express4 = "2*6-7/2";            System.out.println("表达式4:(\"2*6-7/2\") = " + calculator.analysis(express4));            String express5 = "(8-3)*((a+b)/(a-b))";            System.out.println("表达式5:(\"(8-3)*((" + a + "+" + "+" + b + ")/(" + a                    + "-" + b + "))\") = " + calculator.analysis(express5));            String express6 = "13 % 2";            System.out.println("表达式6:(\"13%2\") = " + calculator.analysis(express6));            String express7 = "4^3 * 8 + 2";            System.out                    .println("表达式7:\"3^2 * 5 + 4\") = " + calculator.analysis(express7));        }    }
相关栏目:

用户点评