• 利用栈计算表达式应用——给小朋友出题并计算正答率(并保存数据)


    (一)效果展示

    题库XX.txt

    答题过程

    存储记录文件 xx.txt

    (二)将所需要用到的+,-,等符号封装,然后写几个判断方法

     1  public char[] op = {'+','-','*','/','(',')'};  
     2         public String[] strOp = {"+","-","*","/","(",")"};  
     3         public boolean isDigit(char c){  
     4             if(c>='0'&&c<='9'){  
     5                 return true;  
     6             }  
     7             return false;  
     8         }  
     9         public boolean isOp(char c){  
    10             for(int i=0;i<op.length;i++){  
    11                 if(op[i]==c){  
    12                     return true;  
    13                 }  
    14             }  
    15             return false;  
    16         }  
    17         public boolean isOp(String s){  
    18             for(int i=0;i<strOp.length;i++){  
    19                 if(strOp[i].equals(s)){  
    20                     return true;  
    21                 }  
    22             }  
    23             return false;  
    24         }  

    (三)因为要将题目都转化成String类型进行处理,所以要处理计算式

     1   public List<String> work(String str){  
     2             List<String> list = new ArrayList<String>();  
     3             char c;  
     4             
     5             //StringBuilder 与StringBuffer本质上没什么区别,主要是StringBuilder去掉了保护线程安全那部分的开销 
     6             //append()方法用于字符的拼接
     7             StringBuilder sb = new StringBuilder();  
     8             for(int i=0;i<str.length();i++){  
     9                 c = str.charAt(i);  
    10                 if(isDigit(c)){  
    11                     sb.append(c);  
    12                                }  
    13                 if(isOp(c)){  
    14                     if(sb.toString().length()>0){  
    15                         list.add(sb.toString());  
    16                         sb.delete(0, sb.toString().length());  
    17                     }  
    18                     //c+""为的是符合list<String>的存储参数String类型
    19                     list.add(c+"");  
    20                 }  
    21             }  
    22             //将最后sb中的 数据存到List中并且 清空sb
    23             if(sb.toString().length()>0){  
    24                 list.add(sb.toString());  
    25                 sb.delete(0, sb.toString().length());  
    26             }  
    27             return list;  
    28         }  
    29         public void printList(List<String> list){  
    30             for(String o:list){  
    31                 System.out.print(o+" ");  
    32             }  
    33         }  

    (四)将中缀表达式转化为后缀表达式,然后利用栈进行计算

        public List<String> InfixToPostfix(List<String> list){  
                List<String> Postfixlist = new ArrayList<String>();//存放后缀表达式  
                Stack<String> stack = new Stack<String>();//暂存操作符  
                
                for(int i=0;i<list.size();i++){  
                    
                    
                      //按优先级压栈 
                    String s = list.get(i);  
                    if(s.equals("(")){  
                        stack.push(s);  
                    }else if(s.equals("*")||s.equals("/")){  
                        stack.push(s);  
                    }else if(s.equals("+")||s.equals("-")){  
                        if(!stack.empty()){  
                            while(!(stack.peek().equals("("))){  
                                Postfixlist.add(stack.pop());  
                                if(stack.empty()){  
                                    break;  
                                }  
                            }  
                            stack.push(s);  
                        }else{  
                            stack.push(s);  
                        }  
                    }else if(s.equals(")")){  
                        while(!(stack.peek().equals("("))){  
                            Postfixlist.add(stack.pop());  
                        }  
                        stack.pop();  
                    }else{  
                        Postfixlist.add(s);  
                    }  
                    if(i==list.size()-1){  
                        while(!stack.empty()){  
                            Postfixlist.add(stack.pop());  
                        }  
                    }  
                }  
                return Postfixlist;  
            }  
            /** 
             * 后缀表达式计算 
             */  
            public int doCal(List<String> list){  
                Stack<Integer> stack = new Stack<Integer>();  
                for(int i=0;i<list.size();i++){  
                    String s = list.get(i);  
                    int t=0;  
                    if(!isOp(s)){  
                        t = Integer.parseInt(s);  
                        stack.push(t);  
                    }else{  
                        if(s.equals("+")){  
                            int a1 = stack.pop();  
                            int a2 = stack.pop();  
                            int v = a2+a1;  
                            stack.push(v);  
                        }else if(s.equals("-")){  
                            int a1 = stack.pop();  
                            int a2 = stack.pop();  
                            int v = a2-a1;  
                            stack.push(v);  
                        }else if(s.equals("*")){  
                            int a1 = stack.pop();  
                            int a2 = stack.pop();  
                            int v = a2*a1;  
                            stack.push(v);  
                        }else if(s.equals("/")){  
                            int a1 = stack.pop();  
                            int a2 = stack.pop();  
                            int v = a2/a1;  
                            stack.push(v);  
                        }  
                    }  
                }  
                return stack.pop();  
            }  

    (五)读取文件内容的方法

     1     public String[] getFile(String pathName) throws Exception {
     2             // 【1】先创建一个File的实体对象
     3             File file = new File(pathName);
     4             
     5             if (!file.exists())
     6                 throw new RuntimeException("找不到文件!");
     7             // 【2】加载BUfferedReader流
     8             BufferedReader br = new BufferedReader(new FileReader(file));
     9             String str;
    10             String []arr = null;
    11             // 【3】一行一行读取
    12             while ((str = br.readLine()) != null) {
    13 
    14                 
    15                 // 文件中数据的分割我用的是‘,’具体根据自己的情况调用下面的split()函数
    16                  arr = str.split(",");
    17 
    18             }
    19             return arr;
    20         }

    (六)将记录存储到文件中的方法

            // 将数据存储到文件中
            public  void toFile(String path,int sumOfQ,String []wqs,int []Wresult,String TL,int []result,int[]arr) throws Exception {
                File file = null;
                FileWriter fWriter = null;
                file = new File(path);
                try {
                    if (!file.exists()) {
                        System.out.println("要读入数据的文件不存在");
                    }
                    fWriter = new FileWriter(file);
                    fWriter.write("答题的数量:"+sumOfQ+"
    ");
                    fWriter.write("相应题目:
    ");
                    for (int i = 0; i < sumOfQ; i++) {
                        fWriter.write(wqs[arr[i]]+"
    ");
                    }
                    
                    fWriter.write("你当时的提交答案:  ");
                    for (int i = 0; i < Wresult.length; i++) {
                        fWriter.write(Wresult[i]+" ");
                    }
                    fWriter.write("
    ");
                    
                    fWriter.write("本次答题的正答率: "+TL+"
    ");
                    fWriter.write("本次题目的标准答案: ");
                    for (int i = 0; i < result.length; i++) {
                        fWriter.write(result[i]+" ");
                    }
                    fWriter.write("
    ");
                    fWriter.flush();
    
                } catch (Exception e) {
                    // TODO: handle exception
                    e.printStackTrace();
                } finally {
                    if (fWriter != null) {
                        fWriter.close();
                    }
                }
    
            }

    (七)将标准答案与用户输入答案进行对比,并计算出正答率的方法

     1         // 用来对比用户的答案和标准答案之间的方法
     2                     //参数为用户输入的答案数组
     3     public String compare(int[] a,int[] results,int sumOfQ) {
     4                         double t = 0;
     5                          //将答错的题的序号保存到list中方便调用
     6                         List<Integer> falseQ = new ArrayList<Integer>();
     7                         for (int i = 0; i < results.length; i++) {
     8                             if (a[i] == results[i])
     9                                 t++;
    10                             else {
    11 
    12                                 falseQ.add(Integer.valueOf(i + 1));
    13                             }
    14                         }
    15 
    16                         if (falseQ.isEmpty()) {
    17                             System.out.println("恭喜你,答对了所有题目!");
    18                         } else {
    19                             System.out.print("答题完成,存在问题的序号为:");
    20                             for (int i = 0; i < falseQ.size(); i++) {
    21                                 System.out.print(falseQ.get(i) + " ");
    22                             }
    23                         }
    24                         System.out.println();
    25                         System.out.println("你的正答率为:" + (DF_00(Double.valueOf(t / sumOfQ * 100))) + "%");
    26 
    27                         return String.valueOf(DF_00(Double.valueOf(t / sumOfQ * 100)))+"%";
    28                     }

    (八)对各种数据和运算结果进行规范的方法

    1         public static double DF_00(Double b) {
    2             //调用DecimalForamt类的实例对象 对数据进行位数规范,
    3             //因为规范完后的数据我还要进行操作,我又将它进行强制转化
    4         DecimalFormat dFormat = new DecimalFormat("#.00");
    5         return        Double.parseDouble(dFormat.format(b));
    6                     }    

    (九)用来随机出题的方法

     1                     public int[] suiji(int sumOfQ,String[]wqs) {
     2 
     3                         int[] arr = new int[sumOfQ];
     4                         arr[0] = (int) (Math.floor(Math.random() * (wqs.length)));
     5                         boolean isSame = true;
     6                            int j=0;
     7                         while (isSame == true) {
     8 
     9                             int suiji = (int) (Math.floor(Math.random() * (wqs.length)));
    10                             for (int i = 0; i < arr.length; i++) {
    11                                 if (arr[i] == suiji) {
    12                                     isSame = true;
    13                                     break;
    14                                 } else {
    15                                     isSame = false;
    16                                     continue;
    17                                 }
    18 
    19                             }
    20                             if (!isSame) {
    21 
    22                                 arr[j] = suiji;
    23                                 j++;
    24                                 isSame = true;
    25                             }
    26 
    27                             if (j == 3) {
    28                                 break;
    29                             }
    30                         }
    31                         return arr;
    32                     }                    

    (十)用来让用户输入答案,并保存答案的方法

                        //用来让用户输入答案,并且保存用户输入的答案
                        public int [] Wresult(int sumOfQ) {
                            System.out.println("请依次输入你的答案:");
                            Scanner sc = new Scanner(System.in);
                            String nextLine = sc.nextLine();
    
                            String[] temp = nextLine.split(" ");
    
                            int[] Wresult = new int[sumOfQ];
    
                            for (int i = 0; i < temp.length; i++) {
                                int wResult = Integer.parseInt(temp[i]);
                                Wresult[i] = wResult;
                            }
                            
                            
                            return Wresult;
                        }

    (十一)测试

     1     public static void main(String[] args) {
     2         // TODO Auto-generated method stub
     3 
     4         LV lt = new LV();
     5 
     6         // 获取题目内容
     7         try {
     8             wqs = lt.getFile("数据结构第二阶段.txt");
     9         } catch (Exception e) {
    10             // TODO Auto-generated catch block
    11             e.printStackTrace();
    12         }
    13 
    14         System.out.println("请输入题目数目:");
    15         Scanner scanner = new Scanner(System.in);
    16         int sumOfQ = scanner.nextInt();
    17         
    18          arrs = lt.suiji(sumOfQ, wqs);
    19          
    20          
    21          
    22         results = new int[sumOfQ];
    23         for (int i = 0; i < sumOfQ; i++) {
    24             String str = wqs[arrs[i]];
    25             System.out.println((i + 1) + ":      " + str);
    26             List<String> list = lt.work(str);
    27             List<String> list2 = lt.InfixToPostfix(list);
    28             results[i] = lt.doCal(list2);
    29         }
    30 
    31         
    32         
    33         int[] Wresult = lt.Wresult(sumOfQ);
    34 
    35         
    36         String TL = lt.compare(results, Wresult, sumOfQ);
    37         
    38         
    39         System.out.println("正确答案为:");
    40         for (int i = 0; i < results.length; i++) {
    41             System.out.println((i + 1) + ":  " + results[i]);
    42         }
    43           
    44     
    45         System.out.println("本次答题记录正在为您存储请稍后。。。。。");
    46         Thread thread = new Thread();
    47         
    48         try {
    49             lt.toFile("inputFile.txt", sumOfQ, wqs, Wresult, TL, results,arrs);
    50         } catch (Exception e1) {
    51             // TODO Auto-generated catch block
    52             e1.printStackTrace();
    53         }
    54         
    55         try {
    56             Thread.sleep(1000);
    57             thread.start();
    58             System.out.println("记录已存储至inputFile.txt!");
    59         } catch (InterruptedException e) {
    60             // TODO Auto-generated catch block
    61             e.printStackTrace();
    62         }
    63         
    64 
    65     }
  • 相关阅读:
    python selenium启动配置
    pyqt5安装 + pycharm配置
    Python redis 存取使用
    pycharm 打不开 解决办法
    Python 将图片上传至阿里云OSS对象存储
    mysql表中已有数据,为表新增一个自增id。
    Python 使用BrowserMob Proxy + Selenium 获取Ajax加密数据
    Pycharm 2020.01亲测激活到2089年
    Python3 执行JS出现JSON未定义问题
    pycharm激活,此方法为永久激活。
  • 原文地址:https://www.cnblogs.com/zhang188660586/p/11131880.html
Copyright © 2020-2023  润新知