zoukankan      html  css  js  c++  java
  • :结对项目--四则运算

    成员:林莉  宫丽君

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

     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 }
  • 相关阅读:
    Windows phone 应用开发系列教程(更新中)
    ios实例开发精品文章推荐(8.14)
    Android开发环境——调试器 DDMS相关内容汇总
    docker 发布应用时添加 git revision
    docker环境下数据库的备份(postgresql, mysql)
    golang web 方案
    golang 1.12 自动补全
    区块链简介
    天空的另一半
    Ecto中的changeset,schema,struct,map
  • 原文地址:https://www.cnblogs.com/linliaimeili/p/5918365.html
Copyright © 2011-2022 走看看