:结对项目--四则运算

成员:林莉  宫丽君

经过课上同学的讲解,知道用中缀表达式转化为后缀表达式这种方法可以提高效率,做法如下:

 1 Cal c1=new Cal();
 2 String inBefore = "1+2*3";
 3 String[] in = inBefore.split("") ; 7 public void testSolveOrder() {
 8     HashMap<String, Integer> precedence = new HashMap<String, Integer>();
 9     precedence.put("(", 0);
10     precedence.put(")", 0);
11     precedence.put("+", 1);
12     precedence.put("-", 1);
13     precedence.put("*", 2);
14     precedence.put("/", 2);
15     assertEquals("123*+", c1.SolveOrder(in, precedence));
16     fail("Not yet implemented");
17 }

根据后缀(逆波兰式)计算

 1 public double calculateOut(String[] out) {
 2     //假设满足逆波兰式的输出不为空却长度不为零
 3     assert (out != null && out.length != 0);
 4     //操作数栈
 5     Stack<Double> stack = new Stack<Double>();
 6     for (int i = 0; i < out.length; i++) {
 7         if (isNumber(out[i])) {
 8             stack.push(Double.parseDouble(out[i]));
 9         } else {
10             double v1 = stack.pop();
11             double v2 = stack.pop();
12             double result = eval(out[i], v2, v1);
13             stack.push(result);
14         }
15     }
16     return stack.pop();
17 }

想要产生括号且必须得成对出现,由于是四位数计算,所以穷举出括号的方式获取括号,rand()%5+1生成1-5之间的随机整数,然后选择括号类型。

 1 switch(rand()%5)
 2     {
 3         
 4     case 1:    s = "("+itos(n1)+ope[op1]+itos(n2)+")"+ope[op2]+itos(n3)+ope[op3]+itos(4);break;
 5     case 2:    s = "("+itos(n1)+ope[op1]+itos(n2)+ope[op2]+itos(n3)+")"+ope[op3]+itos(4);break;
 6     case 3:    s = itos(n1)+ope[op1]+"("+itos(n2)+ope[op2]+itos(n3)+")"+ope[op3]+itos(4);break;
 7     case 4:    s = itos(n1)+ope[op1]+"("+itos(n2)+ope[op2]+itos(n3)+ope[op3]+itos(4)+")";break;
 8     case 5: s = "("+itos(n1)+ope[op1]+itos(n2)+")"+ope[op2]+"("+itos(n3)+ope[op3]+itos(4)+")";break;
 9 
10     }

测试是否是数字:

1 @Test
2 public void testIsNumber() {
3     assertEquals("1", "1");
4     assertEquals("0", "+");
5 }

测试单步计算结果:

1 @Test
2 public void testEval() {
3     assertEquals("5", c1.eval("+", 3, 2));
4     assertEquals("6", c1.eval("*", 3, 2));
5     assertEquals("1", c1.eval("-", 3, 2));
6     assertEquals("2", c1.eval("/", 6, 3));
7 }

部分代码如下:

  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 }

 

posted @ 2016-09-28 23:28  林莉  阅读(163)  评论(1编辑  收藏  举报