import java.util.Stack; // import java.util.regex.*; import java.util.Stack; /** * This class use for get calculate result from the String expression * we know that Java language have not class implement method calculate math * expression, JavaScript have implement "eval". * First get simple math expression, iteration wipe out brackets, get expression * in brackets and format with priority, then insert result of formative expression * into original expression, and simplify again * * Support operator "+", "-", "*", "/", "(", ")", "(-)" * use Stack.RegEx * * @author Denua * @version 07 May 2017 11.48 */ public class Interpreter { public static void main(String[] args) { String s = "(1+2)-3*5+(5/5*5+5)-1/2"; Interpreter in = new Interpreter(); System.out.printf("%s = %g",s,in.elv(s)); } /** * public method as the entry * @param str * String expression * @return * double calculate result */ public double elv(String str){ double res = 0.00; res = eval(formate( getSimple(str) ) ); return res; } /** * return String simple expression without brackets,use RegEx check brackets and get * result from the expression in the brackets * @param str * String complex expression * @return String * String simple expression */ private String getSimple(String str){ String res = str; // RegEx matching the expression in brackets Pattern pat2 = Pattern.compile("\\([\\d\\.\\+\\-\\*\\/]+\\)"); // matching Matcher mat = pat2.matcher(str); // if find matching, get simple expression result and joint to origin expression if( mat.find() ){ String find = mat.group(0); String st1 = res.substring(0, str.indexOf(find)); String st2 = res.substring(str.indexOf(find) + find.length(), res.length()); find = find.substring(1, find.length() - 1); find = formate(find); find = String.valueOf(eval(find)); res = st1 + find + st2; // matching again and find expression in brackets, if find, get simple expression Matcher mat2 = pat2.matcher(res); if(mat2.find()){ res = getSimple(res); } } return res; } /** * add brackets for the simple String expression, complete priority, check * each element in the expression * * @param str * String simple expression * @return String * complete priority expression */ private String formate(String str){ String res = str; String[][] part = getPart(res); String[] pt = new String[part[0].length]; for(int q=0; q < pt.length; q++){ pt[q] = ""; } int count = part[0].length; int i = 0; // all case in priority // (*) * // (+) + // (*) + // (+) * // + * (*) + // * (*) + while( i < count){ String id= part[0][i]; String ir = null; if(i < count - 1) ir = part[0][i + 1]; if( nl(id) && nl(ir) ){ if( isf(id) ){ if( isf(ir) ){ pt[i+1] += ")"; } else if( ! isf(ir) ){ pt[i+1] += ")"; int idx = i - 1; while( idx >= 0 ){ String si = part[0][idx]; if( ! isf(si) ){ pt[i+1] = "))"; break; } idx--; } } } if( ! isf(id) ){ if( ! isf(ir) ) pt[i+1] += ")"; } } else if( nl(id) && ! nl(ir)){ if( isf(id) ){ int ix = i - 1; boolean find = false; while( ix >= 0 ){ String six = part[0][ix]; if( ! isf(six) ){ find = true; break; } ix--; } if(find) part[1][i+1] += "))"; else part[1][i + 1] += ")"; } else part[1][i + 1] += ")"; } else{ return null; } i++; } res = ""; for(int j = 0; j < part[0].length; j ++){ part[0][j] = pt[j] + part[0][j]; res =res + part[1][j] + part[0][j]; } res += part[1][part[1].length -1]; return res; } /** * use two Stack calculate expression with complete priority, one Stack * save number another save operator, check each element in the expression * with complete priority, if current element is number, then add to * number Stack, if operator, add to operator Stack, else is ")" , extract * two number from the number Stack, extract operator from the operator Stack * and add result to number Stack, iteration get final result. * * @param str * Complete priority expression * @return double * the result of the expression */ private Double eval(String str){ Stack<String> operate = new Stack<String>(); Stack<Double> value = new Stack<Double>(); String[] ele = getEle(str); int i = 0; while( i < ele.length){ String s = ele[i]; if(s.equals("(")){ } else if(s.equals("+")) operate.push(s) ; else if(s.equals("-")) operate.push(s) ; else if(s.equals("*")) operate.push(s) ; else if(s.equals("/")) operate.push(s) ; else if(s.equals("s")) operate.push(s) ; else if(s.equals(")")){ String op = operate.pop(); double vl = value.pop(); if(op.equals("+")) vl = value.pop() + vl; else if(op.equals("-")) vl = value.pop() - vl; else if(op.equals("*")) vl = value.pop() * vl; else if(op.equals("/")) vl = value.pop() / vl; else if(op.equals("s")) vl = Math.sqrt(vl); value.push(vl); } else{ value.push(Double.parseDouble(s)); } i++; } return value.pop(); } /** * get each part of the expression, cut expression and transform to Array * @param str complete priority expression * @return String[] */ private String[] getEle(String str){ Stack<String> st = new Stack<String>(); int j = 0; String numbTemp = ""; while( j < str.length()){ char temp = str.charAt(j); if( isNum(temp) || temp == ‘.‘ || ( j == 0 && temp == ‘-‘) || ( temp == ‘-‘ && isOp(str.charAt(j - 1)) ) ){ numbTemp += temp; } else if( ! isNum(temp) ){ if( !numbTemp.isEmpty()){ st.push(numbTemp); numbTemp = ""; } st.push(String.valueOf(temp)); } j++; } String[] res = new String[st.size()]; for(int i = st.size() - 1; i >= 0; i -- ){ res[i] = st.pop(); } return res; } private String[][] getPart(String str){ String res = str; int i = 0; Stack<String> cal = new Stack<String>(); Stack<String> op = new Stack<String>(); String num = ""; while( i < res.length()){ char temp = res.charAt(i); if( isOp(temp) ){ if(temp == ‘-‘ && i == 0) num += "-"; else if( temp == ‘-‘ && isOp(res.charAt(i-1)) ) num += "-"; else op.push(String.valueOf(temp)); } else if(isNum(temp)){ num += String.valueOf(temp); if(i >= str.length()){ break; } else{ if( i == str.length() - 1){ String n = String.valueOf(str.charAt(i)); if( isNum(n) && isNum(String.valueOf(str.charAt(i-1)))){ num += n; } else{ num = n; } } else{ String n = String.valueOf(str.charAt(i + 1)); boolean flag = true; while( isNum(n) && flag){ num += n; i ++; if( i > res.length() - 2){ flag = false; }else{ n = String.valueOf(str.charAt(i + 1)); } } } } cal.push(num); num = ""; } else if(temp == ‘)‘){ op.push(")"); } i++; } i = 0; String[][] part = new String[2][]; String[] temp1 = new String[op.size()]; String[] temp2 = new String[cal.size()]; for(Object o:op.toArray()){ temp1[i] = (String) o; i++; } i = 0; for(Object o:cal.toArray()){ temp2[i] = (String) o; i++; } part[0] = temp1; part[1] = temp2; return part; } private boolean isNum(String str){ return str.equals("0") || str.equals("1") || str.equals("2") || str.equals("3") || str.equals("4") || str.equals("5") || str.equals("6") || str.equals("7") || str.equals("8") || str.equals("9") || str.equals("."); } private boolean isOp(char str){ return str == ‘s‘ || str == ‘+‘ ||str == ‘-‘ || str == ‘*‘ || str == ‘/‘ ; } private boolean isNum(char str){ return str == ‘0‘ || str == ‘1‘ || str == ‘2‘ || str == ‘3‘ || str == ‘4‘ || str == ‘5‘ || str == ‘6‘ || str == ‘7‘ || str == ‘8‘ || str == ‘9‘ || str == ‘.‘ ; } private boolean isf(String str){ return str.equals("*") || str.equals("/"); } private boolean nl(Object obj){ return obj != null; } }
本文出自 “12883274” 博客,请务必保留此出处http://12893274.blog.51cto.com/12883274/1922908
原文地址:http://12893274.blog.51cto.com/12883274/1922908