上一周的四则运算有bug,这次补充正确代码:
1 // 中缀转后缀 2 public String[] SolveOrder(String[] in, HashMap<String, Integer> precedence) { 3 // 符合逆波兰式(后缀)的输出 4 int kk=in.length; 5 String out[] = new String[kk]; 6 int p = 0 ; 7 // 操作符 8 Stack<String> ops = new Stack<String>(); 9 for (int i = 0; i < in.length; i++) { 10 String s = in[i]; 11 // 碰见数值 就放进out数组末尾 12 if (!precedence.containsKey(in[i])) { 13 out[p] = s ; 14 p ++ ; 15 continue; 16 } 17 //如果优先级比栈顶的大 18 if (ops.isEmpty() || (precedence.get(s) > precedence.get(ops.peek()))) { 19 ops.push(s); 20 //break; 21 }else{ 22 //如果栈顶的比目前的运算符优先级小或者相等 一直出栈到没有或者栈顶 小于当前运算符 23 while (true ) { 24 ops.pop();// 出栈得运算符 25 out[p] = s ; 26 p ++ ; 27 if(ops.empty()) break ;//如果栈空了 break 28 if(precedence.get(ops.peek()) < precedence.get(s)){ 29 break ;//栈顶小于当前的了 break 30 } 31 } 32 out[p] = s ; 33 p ++ ; 34 } 35 } 36 // 若操作符栈不为空,就依次将剩余的操作符放入out数组 37 while (!ops.isEmpty()) { 38 out[p] = ops.peek() ; 39 p ++ ; 40 ops.pop() ; 41 } 42 return out; 43 } 44 45 // 优先级的定义 46 public HashMap<String, Integer> priorityInfo() { 47 HashMap<String, Integer> precedence = new HashMap<String, Integer>(); 48 precedence.put("(", 0); 49 precedence.put(")", 0); 50 precedence.put("+", 1); 51 precedence.put("-", 1); 52 precedence.put("*", 2); 53 precedence.put("/", 2); 54 return precedence; 55 } 56 57 public double calculateOut(String[] out) { 58 // 假设满足逆波兰式的输出不为空却长度不为零 59 int kk=out.length; 60 System.out.println("转换成后缀表达式是"); 61 for(int o=0;o<kk;o++){ 62 System.out.print(out[o]); 63 } 64 System.out.println(); 65 assert (out != null && out.length != 0); 66 // 操作数栈 67 Stack<Double> stack = new Stack<Double>(); 68 for (int i = 0; i < out.length; i++) { 69 if (isNumber(out[i])) { 70 stack.push(Double.parseDouble(out[i])); 71 } else { 72 double v1 = stack.pop(); 73 double v2 = stack.pop(); 74 double result = eval(out[i], v2, v1); 75 stack.push(result); 76 } 77 } 78 return stack.pop(); 79 } 80 81 // 判别是否是数字 82 public boolean isNumber(String s) { 83 if (s.equals("+") || s.equals("-") || s.equals("*") || s.equals("/")) 84 return false; 85 return true; 86 } 87 88 public static double eval(String op, double val1, double val2) { 89 if (op.equals("+")) 90 return val1 + val2; 91 if (op.equals("-")) 92 return val1 - val2; 93 if (op.equals("/")) 94 return val1 / val2; 95 if (op.equals("*")) 96 return val1 * val2; 97 throw new RuntimeException("Invalid operator"); 98 } 99 public static void main(String[] args) { 100 System.out.println("请输入要计算的算式:"); 101 Scanner sc = new Scanner(System.in); 102 String inBefore = sc.nextLine(); 103 String[] in = inBefore.split("") ; 104 int kk=in.length; 105 System.out.println("您输入的算式是"); 106 for(int o=0;o<kk;o++){ 107 System.out.print(in[o]); 108 } 109 System.out.println(); 110 Cal cc = new Cal() ; 111 HashMap<String, Integer> precedence = cc.priorityInfo(); 112 String[] out = cc.SolveOrder(in, precedence); 113 System.out.println("所输入的算式结果为:" + cc.calculateOut(out)); 114 115 }
运行结果如下:
单元测试代码如下:
测试中缀转后缀
Cal c1=new Cal(); String inBefore = "1+2*3"; String[] in = inBefore.split("") ; @Test public void testSolveOrder() { HashMap<String, Integer> precedence = new HashMap<String, Integer>(); precedence.put("(", 0); precedence.put(")", 0); precedence.put("+", 1); precedence.put("-", 1); precedence.put("*", 2); precedence.put("/", 2); assertEquals("123*+", c1.SolveOrder(in, precedence)); fail("Not yet implemented"); }
测试计算结果是否正确
@Test public void testCalculateOut() { assertEquals("7.0", c1.calculateOut(in)); }
测试是否是数字:
@Test public void testIsNumber() { assertEquals("1", "1"); assertEquals("0", "+"); }
测试Eval()单步计算结果:
@Test public void testEval() { assertEquals("5", c1.eval("+", 3, 2)); assertEquals("6", c1.eval("*", 3, 2)); assertEquals("1", c1.eval("-", 3, 2)); assertEquals("2", c1.eval("/", 6, 3)); }
运行结果如下:
现在实现的手动输入字符串算式,scanner识别,拆分在进行计算。
四则运算psp:
时间: 2024-10-27 03:08:03