mathexpression.java
来自「一个小型的数据挖掘器应用软件,综合数据挖掘的各种功能」· Java 代码 · 共 946 行 · 第 1/3 页
JAVA
946 行
throw new Exception("Unknow function " + f); } if (arity[i] != ops.size()) { throw new Exception("Wrong Number of argument in " + f); } type = Tokenizer.TT_FUN; nval = i; operands = new TreeNode[ops.size()]; for(i=0;i<operands.length;i++) { operands[i] = (TreeNode) ops.elementAt(i); } } /** * Construct an operator node * * @param t the operator '+','-','*','/' * @param ops the operands of the operator * @throws Exception is something goes wrong */ TreeNode(int t,Vector ops) throws Exception { type = t; operands = new TreeNode[ops.size()]; for(int i=0;i<operands.length;i++) { operands[i] = (TreeNode) ops.elementAt(i); } } /** * Evaluate the tree with for specific values of the variables * * @param symbols a map associating a Double value to each variable name * @return the evaluation * @throws Exception if a symbol, function or node type is unknown */ public double eval(Map symbols) throws Exception { switch (type) { case Tokenizer.TT_NUMBER: return nval; case Tokenizer.TT_VAR: if (!symbols.containsKey(sval)) { throw new Exception("Unknow symbol " + sval); } return ((Double) symbols.get(sval)).doubleValue(); case '+': return operands[0].eval(symbols) + operands[1].eval(symbols); case '-': if (operands.length > 1) { return operands[0].eval(symbols) - operands[1].eval(symbols); } else { return -operands[0].eval(symbols); } case '*': return operands[0].eval(symbols) * operands[1].eval(symbols); case '/': return operands[0].eval(symbols) / operands[1].eval(symbols); case '>': return (operands[0].eval(symbols) > operands[1].eval(symbols))?1.0:0.0; case '<': return (operands[0].eval(symbols) < operands[1].eval(symbols))?1.0:0.0; case '=': return (operands[0].eval(symbols) == operands[1].eval(symbols))?1.0:0.0; case '&': return (operands[0].eval(symbols)==1.0) && (operands[1].eval(symbols)==1.0)?1.0:0.0; case '|': return (operands[0].eval(symbols)==1.0) || (operands[1].eval(symbols)==1.0)?1.0:0.0; case '!': return (operands[0].eval(symbols)==1.0)?0.0:1.0; case Tokenizer.TT_FUN: switch ((int) nval) { case 0: return Math.abs(operands[0].eval(symbols)); case 1: return Math.sqrt(operands[0].eval(symbols)); case 2: return Math.log(operands[0].eval(symbols)); case 3: return Math.exp(operands[0].eval(symbols)); case 4: return Math.sin(operands[0].eval(symbols)); case 5: return Math.cos(operands[0].eval(symbols)); case 6: return Math.tan(operands[0].eval(symbols)); case 7: return Math.rint(operands[0].eval(symbols)); case 8: return Math.floor(operands[0].eval(symbols)); case 9: return Math.pow(operands[0].eval(symbols), operands[1].eval(symbols)); case 10:return Math.ceil(operands[0].eval(symbols)); default: throw new Exception("Unknow Function"); } case Tokenizer.TT_IFELSE: return (operands[0].eval(symbols)==1.0)?operands[1].eval(symbols):operands[2].eval(symbols); default:throw new Exception("Unknow Tree Node Type."); } } } /** * Construct the Expression tree for a given String * * @param exp the expression used to build the tree * @return the generated node * @throws Exception if EOF is not reached */ public static TreeNode parse(String exp) throws Exception { Tokenizer tokenizer = new Tokenizer(new StringReader(exp)); tokenizer.nextToken(); TreeNode res = parseExp(tokenizer); if (tokenizer.ttype != Tokenizer.TT_EOF) { throw new Exception("Syntax Error: end of file expected."); } return res; } /** * Parse the exp rule * * @param tokenizer the tokenizer from which the token are extracted. * @return the tree of the corresponding expression * @throws Exception if something goes wrong */ public static TreeNode parseExp(Tokenizer tokenizer) throws Exception { Vector operands = new Vector(); operands.add(parseTerm(tokenizer)); switch (tokenizer.ttype) { case '+': tokenizer.nextToken(); operands.add(parseExp(tokenizer)); return new TreeNode('+',operands); case '-': tokenizer.nextToken(); operands.add(parseExp(tokenizer)); return new TreeNode('-',operands); default: return (TreeNode) operands.get(0); } } /** * Parse the term rule * * @param tokenizer the tokenizer from which the token are extracted. * @return the tree of the corresponding term * @throws Exception if something goes wrong */ public static TreeNode parseTerm(Tokenizer tokenizer) throws Exception { Vector operands = new Vector(); operands.add(parseAtom(tokenizer)); switch (tokenizer.ttype) { case '*': tokenizer.nextToken(); operands.add(parseTerm(tokenizer)); return new TreeNode('*',operands); case '/': tokenizer.nextToken(); operands.add(parseTerm(tokenizer)); return new TreeNode('/',operands); default: return (TreeNode) operands.get(0); } } /** * Parse the atom rule * * @param tokenizer the tokenizer from which the token are extracted. * @return the tree of the corresponding atom * @throws Exception if a syntax error occurs */ public static TreeNode parseAtom(Tokenizer tokenizer) throws Exception { switch (tokenizer.ttype) { case Tokenizer.TT_NUMBER: TreeNode res = new TreeNode(tokenizer.nval); tokenizer.nextToken(); return res; case '(': tokenizer.nextToken(); TreeNode e = parseExp(tokenizer); if (tokenizer.ttype != ')') { throw new Exception("Syntax Error: ')' expected."); } tokenizer.nextToken(); return e; case '-': tokenizer.nextToken(); Vector operands = new Vector(1); operands.add(parseAtom(tokenizer)); return new TreeNode('-',operands); case Tokenizer.TT_VAR: TreeNode t = new TreeNode(tokenizer.sval); tokenizer.nextToken(); return t; case Tokenizer.TT_IFELSE: tokenizer.nextToken(); if (tokenizer.ttype != '(') { throw new Exception("Syntax Error: '(' expected."); } tokenizer.nextToken(); Vector par = new Vector(3); par.add(parseDisjunction(tokenizer)); if (tokenizer.ttype != ',') throw new Exception("Syntax Error: ',' expected."); tokenizer.nextToken(); par.add(parseExp(tokenizer)); if (tokenizer.ttype != ',') throw new Exception("Syntax Error: ',' expected."); tokenizer.nextToken(); par.add(parseExp(tokenizer)); if (tokenizer.ttype != ')') throw new Exception("Syntax Error: ',' expected."); tokenizer.nextToken(); return new TreeNode(par); case Tokenizer.TT_FUN: String fn = tokenizer.sval; tokenizer.nextToken(); if (tokenizer.ttype != '(') throw new Exception("Syntax Error: '(' expected."); tokenizer.nextToken(); Vector params = new Vector(1); params.add(parseExp(tokenizer)); while (tokenizer.ttype == ',') { tokenizer.nextToken(); params.add(parseExp(tokenizer)); } if (tokenizer.ttype != ')') throw new Exception("Syntax Error: ')' expected."); tokenizer.nextToken(); return new TreeNode(fn,params); default: throw new Exception("Syntax Error: Unexpected token"); } } /** * Disjunctive boolean test * * @param tokenizer the tokenizer from which the token are extracted. * @return the tree of the corresponding Dijunction * @throws Exception if something goes wrong */ public static TreeNode parseDisjunction(Tokenizer tokenizer) throws Exception { Vector params = new Vector(2); params.add(parseConjunction(tokenizer)); if (tokenizer.ttype != '|') { return (TreeNode) params.get(0); } tokenizer.nextToken(); params.add(parseDisjunction(tokenizer)); return new TreeNode('|',params); } /** * Conjunction boolean test * * @param tokenizer the tokenizer from which the token are extracted. * @return the tree of the corresponding Conjunction * @throws Exception if something goes wrong */ public static TreeNode parseConjunction(Tokenizer tokenizer) throws Exception { Vector params = new Vector(2); params.add(parseNumTest(tokenizer)); if (tokenizer.ttype != '&') { return (TreeNode) params.get(0); } tokenizer.nextToken(); params.add(parseConjunction(tokenizer)); return new TreeNode('&',params); } /** * Parse a numeric test * * @param tokenizer the tokenizer from which the token are extracted. * @return the tree of the corresponding test * @throws Exception if brackets don't match or test unknown */ public static TreeNode parseNumTest(Tokenizer tokenizer) throws Exception { TreeNode n; switch (tokenizer.ttype) { case '[': tokenizer.nextToken(); n = parseDisjunction(tokenizer); if (tokenizer.ttype != ']') { throw new Exception("']' expected"); } tokenizer.nextToken(); return n; case '!': tokenizer.nextToken(); if (tokenizer.ttype != '[') { throw new Exception("'[' expected after '!'"); } tokenizer.nextToken(); n = parseDisjunction(tokenizer); if (tokenizer.ttype != ']') { throw new Exception("']' expected"); } tokenizer.nextToken(); return new TreeNode(n); default: Vector params = new Vector(2); params.add(parseExp(tokenizer)); int op = tokenizer.ttype; if (op != '<' && op != '>' && op != '=') { throw new Exception("Unknow test " + (char) tokenizer.ttype); } tokenizer.nextToken(); params.add(parseExp(tokenizer)); return new TreeNode(op,params); } } } /** * Main method for testing this class. * * @param argv should contain arguments to the filter: * use -h for help */ public static void main(String [] argv) { try { if (Utils.getFlag('b', argv)) { Filter.batchFilterFile(new MathExpression(), argv); } else { Filter.filterFile(new MathExpression(), argv); } } catch (Exception ex) { ex.printStackTrace(); System.out.println(ex.getMessage()); } }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?