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

(一)效果展示

题库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+"\n");
                fWriter.write("相应题目:\n");
                for (int i = 0; i < sumOfQ; i++) {
                    fWriter.write(wqs[arr[i]]+"\n");
                }
                
                fWriter.write("你当时的提交答案:  ");
                for (int i = 0; i < Wresult.length; i++) {
                    fWriter.write(Wresult[i]+" ");
                }
                fWriter.write("\n");
                
                fWriter.write("本次答题的正答率: "+TL+"\n");
                fWriter.write("本次题目的标准答案: ");
                for (int i = 0; i < result.length; i++) {
                    fWriter.write(result[i]+" ");
                }
                fWriter.write("\n");
                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     }

 

posted @ 2019-07-04 13:27  我叫张小凡  阅读(442)  评论(0编辑  收藏  举报