网上看到的一种很给力的实现方法,利用递归。
/** * 思路 * 1、排除空字符串 * 2、得到第一个符号的索引 * 3、假如只存在数字,直接转换并返回 * 4、假如存在左括号,则找到右括号,并将括号里面的字符串递归计算,并替换,然后整体递归,去掉所有括号 * 5、先递归分解加减,保证乘除的优先级 * 6、再递归分解乘除,乘除计算完后会自动的回溯计算加减 * @param s * @return * @throws Exception */ public static float opt(String s) throws Exception{ //1 if(s == null || "".equals(s.trim())) { return 0f; } //2 int a1=s.indexOf('+'); int a2=s.indexOf('-'); int a3=s.indexOf('*'); int a4=s.indexOf('/'); int a5=s.indexOf('('); //3 计算单独的数字 if(a1==-1&&a2==-1&&a3==-1&&a4==-1){ if(s.trim()==null||"".equals(s.trim())){ throw new Exception("operate error"); } return Float.parseFloat(s.trim()); } //4先计算括号 if(a5!=-1){ int a6=s.lastIndexOf(')'); if(a6==-1){ throw new Exception("括号不匹配"); }else{ float f=opt(s.substring(a5+1,a6).trim()); s=s.replace(s.substring(a5,a6+1), String.valueOf(f)); return opt(s); } } //5先按加减拆开,保证乘除的优先级 if(a1!=-1){ return opt(s.substring(0,a1))+opt(s.substring(a1+1,s.length())); } if(a2!=-1){ return opt(s.substring(0,a2))-opt(s.substring(a2+1,s.length())); } //6 if(a3!=-1){ return opt(s.substring(0,a3))*opt(s.substring(a3+1,s.length())); } if(a4!=-1){ return opt(s.substring(0,a4))/opt(s.substring(a4+1,s.length())); } return Integer.parseInt(s.trim()); }
还有一种更便捷的方法,利用内置的JS引擎
public static Object jsCalculate(String script) { ScriptEngineManager manager = new ScriptEngineManager(); ScriptEngine engine = manager.getEngineByName("javascript"); try { return (Object) engine.eval(script); } catch (ScriptException ex) { ex.printStackTrace(); } return null; }