PSP阶段 |
预计花费时间(小时) |
实际花费时间(小时) |
计划 |
0.5 |
1 |
明确需求和其他相关因素,估计每个阶段的时间成本 |
0.5 |
0.5 |
开发 |
4 |
2 |
需求分析 |
1 |
0.5 |
代码规范 |
1 |
0.5 |
具体设计 |
1 |
2 |
具体编码 |
2 |
2 |
代码复审 |
1 |
1 |
测试(自测,修改代码,提交修改) |
2 |
|
private static double doubleCal(double a1, double a2, char operator) throws Exception { switch (operator) { case '+': return a1 + a2; case '-': return a1 - a2; case '*': return a1 * a2; case '/': return a1 / a2; default: break; } throw new Exception("illegal operator!"); }
写一个获得优先级的方法:
private static int getPriority(String s) throws Exception { if(s==null) return 0; switch(s) { case "(":return 1; case "+":; case "-":return 2; case "*":; case "/":return 3; default:break; } throw new Exception("illegal operator!"); }
解析表达式:
public static String getResult(String expr) throws Exception { System.out.println("计算"+expr); /*数字栈*/ Stack<Double> number = new Stack<Double>(); /*符号栈*/ Stack<String> operator = new Stack<String>(); operator.push(null);// 在栈顶压人一个null,配合它的优先级,目的是减少下面程序的判断 /* 将expr打散为运算数和运算符 */ Pattern p = Pattern.compile("(?<!\\d)-?\\d+(\\.\\d+)?|[+\\-*/()]");// 这个正则为匹配表达式中的数字或运算符 Matcher m = p.matcher(expr); while(m.find()) { String temp = m.group(); if(temp.matches("[+\\-*/()]")) {//遇到符号 if(temp.equals("(")) {//遇到左括号,直接入符号栈 operator.push(temp); System.out.println("符号栈更新:"+operator); }else if(temp.equals(")")){//遇到右括号,"符号栈弹栈取栈顶符号b,数字栈弹栈取栈顶数字a1,数字栈弹栈取栈顶数字a2,计算a2 b a1 ,将结果压入数字栈",重复引号步骤至取栈顶为左括号,将左括号弹出 String b = null; while(!(b = operator.pop()).equals("(")) { System.out.println("符号栈更新:"+operator); double a1 = number.pop(); double a2 = number.pop(); System.out.println("数字栈更新:"+number); System.out.println("计算"+a2+b+a1); number.push(doubleCal(a2, a1, b.charAt(0))); System.out.println("数字栈更新:"+number); } System.out.println("符号栈更新:"+operator); }else {//遇到运算符,满足该运算符的优先级大于栈顶元素的优先级压栈;否则计算后压栈 while(getPriority(temp) <= getPriority(operator.peek())) { double a1 = number.pop(); double a2 = number.pop(); String b = operator.pop(); System.out.println("符号栈更新:"+operator); System.out.println("数字栈更新:"+number); System.out.println("计算"+a2+b+a1); number.push(doubleCal(a2, a1, b.charAt(0))); System.out.println("数字栈更新:"+number); } operator.push(temp); System.out.println("符号栈更新:"+operator); } }else {//遇到数字,直接压入数字栈 number.push(Double.valueOf(temp)); System.out.println("数字栈更新:"+number); } } while(operator.peek()!=null) {//遍历结束后,符号栈数字栈依次弹栈计算,并将结果压入数字栈 double a1 = number.pop(); double a2 = number.pop(); String b = operator.pop(); System.out.println("符号栈更新:"+operator); System.out.println("数字栈更新:"+number); System.out.println("计算"+a2+b+a1); number.push(doubleCal(a2, a1, b.charAt(0))); System.out.println("数字栈更新:"+number); } return number.pop()+""; }
主方法,以-3.5*(4.5-(4+(-1-1/2)))测试
public static void main(String[] args) throws Exception { String str = "-3.5*(4.5-(4+(-1-1/2)))"; System.out.println(getResult(str)); }