小学生四则运算练习软件项目报告

一、项目Github地址

https://github.com/LilyFuEnLi/Arithmetic_SE

(注:附上coding.net项目网址:https://git.coding.net/LilyF/Software.git,coding.net与GitHub功能相同,coding.net的语言为中文,而GitHub是英文。)

二、项目报告

1、需求分析

(1)程序可接收一个输入参数n,然后随机产生n道加减乘除练习题,每个数字在 0 和 100 之间,运算符在3个到5个之间,即运算数字在4~6个之间。

(2)为了让小学生得到充分锻炼,每个练习题至少要包含2种运算符。同时,由于小学生没有分数与负数的概念,你所出的练习题在运算过程中不得出现负数与非整数,比如不能出 3/5+2=2.6,2-5+10=7等算式。

(3)练习题生成好后,将自己的学号与生成的n道练习题及其对应的正确答案输出到文件“result.txt”中,不要输出额外信息,文件目录与程序目录一致。

(4)当程序接收的参数为5时,即产生5个运算式,以下为我试验中输出的文件,第一行为我的学号。

201571030108
(44*66)+(67-54)=2917
(43+54)-22*(37-37)=97
(74+35)*63+(17-17)=6867
(58+54)-(18+54)=50
(24+65)-(9+50)=30

(5)附加功能:支持有括号的运算式,包括出题与求解正确答案。由于随机产生的运算数字为4~6个,所以算式中存在的括号设置为2个。

2、功能设计

(1)屏幕打印提示输入需要产生的运算式个数number。

(2) 生成一个包含4~6个数字,3~5个运算符且包含两个括号的字符串表达式。
(3)屏幕依次显示number个运算式,要求学生解答,并显示答题是否正确。

(5)计算出表达式的结果,并且运算过程中不能出现负数。

(4)统计学生答题情况,计算并显示学生的正确率。

(5)最后将运算表达式和计算结果写入result.txt文件,提示学生进行查询并复习。

3、设计实现

      目含有两个java文件,分别是Main.java与Calculate_SE .java,Calculate_SE .java中包含calaulate_AE(产生随机运算式)、transferToPostfix(中缀表达式转化为逆波兰式)、calculate(计算逆波兰式)等方法,Main调用Calculate_SE中的各个方法完成项目,设计流程图如图1所示。

图 1 设计流程图

4、测试运行

      运行Main.java文件,输入产生运算式个数number为5,依次进行答题(如图2所示),同时生成result.txt文件,如图3所示,cmd运行文件run.bat文件截图如图4所示。

 

 

 

                               图2                                                                                                                                                           图3

 

图 4

 5、核心代码

 

(1)生成随机运算式,调用方法计算结果

 1 public void calaulate_AE(int number) {
 2         int Right=0;
 3         float R = 0;
 4         int F=0;
 5         while(F==0)
 6         {
 7         for(int i=0;i<number;i++)
 8         {
 9             CN[i]=(int)(Math.random()*2+4);
10             int Bracket=(int)(Math.random()*CN[i]-2);
11             for(int j=0;j<CN[i];j++)
12             {
13                 N[i][j]=(int) (Math.random()*100+1);
14             }
15             for(int k=0;k<CN[i]-1;k++)
16             {
17                 C[i][k]=Str[(int)(Math.random()*3)];    
18             }
19             for(int k=0;k<CN[i]-1;k++)
20             {
21                while(C[i][0]==C[i][1])
22                     C[i][1]=Str[(int)(Math.random()*3)];
23                 if(C[i][k]=='-' && (N[i][k]<N[i][k+1]))
24                 {
25                     int temp=0;
26                     temp=N[i][k];
27                     N[i][k+1]=temp;
28                     N[i][k]=temp;
29                 }
30                 if(C[i][k]=='/' && (N[i][k]%N[i][k+1]!=0))
31                 {
32                     int temp=N[i][k];
33                     N[i][k] = N[i][k] <N[i][k+1]? N[i][k]: N[i][k+1];
34                     N[i][k+1] = temp > N[i][k+1]? temp: N[i][k+1];
35                     for(int num = N[i][k]; num >= 1; num--)
36                     {
37                         if(N[i][k] % num == 0 && N[i][k+1] % num == 0)
38                         {
39                             N[i][k+1]=num;
40                             break;
41                         }
42                     }
43                 }
44             }
45             String AE=new String();
46             LinkedList<String> list=new LinkedList<>();
47             list.add(String.valueOf('('));
48             list.add(String.valueOf(N[i][0]));
49             list.add(String.valueOf(C[i][0]));
50             list.add(String.valueOf(N[i][1]));
51             list.add(String.valueOf(')'));
52             list.add(String.valueOf(C[i][1]));
53             AE+='('+String.valueOf(N[i][0])+String.valueOf(C[i][0])+String.valueOf(N[i][1])+')'+String.valueOf(C[i][1]);
54                 for(int j=2;j<CN[i]-2;j++)
55                 {
56                         list.add(String.valueOf(N[i][j]));
57                         list.add(String.valueOf(C[i][j]));
58                         AE+=String.valueOf(N[i][j])+String.valueOf(C[i][j]);
59                 }
60                 list.add(String.valueOf('('));
61                 list.add(String.valueOf(N[i][CN[i]-2]));
62                 list.add(String.valueOf(C[i][CN[i]-2]));
63                 list.add(String.valueOf(N[i][CN[i]-1]));
64                 list.add(String.valueOf(')'));
65                 AE+='('+String.valueOf(N[i][CN[i]-2])+String.valueOf(C[i][CN[i]-2])+String.valueOf(N[i][CN[i]-1])+')'+'=';
66                 String sum=transferToPostfix(list);
67                 char fir =sum.charAt(0);
68                 if(fir=='-')
69                     F=0;
70                 else
71                     F=1;
72                 System.out.print(AE);
73                 String SUM=scanner.nextLine();
74                 if(SUM.equals(sum))
75                 {
76                     System.out.print("回答真确,Very Good!(*^▽^*):\n");
77                     Right++;
78                 }
79                 else
80                     System.out.print("回答错误,要加油哦!(*^▽^*):\n");
81                 float R1 = (float)Right;
82                 float R2 = (float)number;
83                 R=(float) (R1/R2*100.00);
84                 AE+=sum;
85                 Arithmetic.add(AE);
86         }
87         System.out.print("本次答题共计"+number+"道,回答正确"+Right+"道,正确率为"+R+"%.\n");
88     }
89     }
View Code


(2)中缀表达式转为后缀表达式

private static String transferToPostfix(LinkedList<String> list){
        Iterator<String> it=list.iterator();
        while (it.hasNext()) 
        {
            String s = it.next();
            if (isOperator(s)) 
            {
                if (operators.isEmpty()) 
                {
                    operators.push(s);
                }
                else 
                {//如果读入的操作符为非")"且优先级比栈顶元素的优先级高或一样,则将操作符压入栈
                    if (priority(operators.peek())<=priority(s)&&!s.equals(")")) 
                    {
                        operators.push(s);
                    }
                    else if(!s.equals(")")&&priority(operators.peek())>priority(s))
                    {
                        while (operators.size()!=0&&priority(operators.peek())>=priority(s)&&!operators.peek().equals("(")) 
                        {
                            if (!operators.peek().equals("(")) 
                            {
                                String operator=operators.pop();
                                sb.append(operator).append(" ");
                                output.push(operator);
                            }
                        }
                        operators.push(s);
                    }
                    //如果读入的操作符是")",则弹出从栈顶开始第一个"("及其之前的所有操作符
                    else if (s.equals(")")) 
                    {
                        while (!operators.peek().equals("(")) 
                        {
                            String operator=operators.pop();
                            sb.append(operator).append(" ");
                            output.push(operator);
                        }
                        //弹出"("
                        operators.pop();
                    }
                }
            }
            //读入的为非操作符
            else 
            {
                sb.append(s).append(" ");
                output.push(s);
            }
        }
        if (!operators.isEmpty()) 
        {
            Iterator<String> iterator=operators.iterator();
            while (iterator.hasNext()) 
            {
                String operator=iterator.next();
                sb.append(operator).append(" ");
                output.push(operator);
                iterator.remove();
            }
        }
        String sum= calculate();
       return sum;
    }
View Code

 

(3)根据后缀表达式计算结果

  private static String calculate(){
        LinkedList<String> mList=new LinkedList<>();
        String[] postStr=sb.toString().split(" ");
        for (String s:postStr) 
        {
            if (isOperator(s))
            {
                if (!mList.isEmpty())
                {
                    int num1=Integer.valueOf(mList.pop());
                    int num2=Integer.valueOf(mList.pop());
                    int newNum=cal(num2,num1,s);
                    mList.push(String.valueOf(newNum));
                }
            }
            else 
            { //数字则压入栈中
                mList.push(s);
            }
        }
        if (!mList.isEmpty())
        {
            return mList.pop();
        }
        return null;
    }
View Code

 

6、总结

       在本次项目中,我建立了两个java文件,分别是Main.java与Calculate_SE .java,Calculate_SE .java用于整体的方法实现,其中包含calaulate_AE(产生随机运算式)、transferToPostfix(中缀表达式转化为逆波兰式)、calculate(计算逆波兰式)等方法,然后利用Main调用Calculate_SE中的各个方法完成整体项目。实现小学生四则运算练习软件的设计,加入了附加功能(括号运算),但未能实现分数运算,后期我会继续学习改进,使其功能较为完善。

7、展示PSP

PSP2.1任务内容计划完成的时间(min)实际完成需要的时间(min)
PLanning 计划 30 30
Estimate 估计这个任务需要多少时间,并规划大致工作步骤 30 40
Developmet 开发 240 360
Analysis 需求分析(包括学习新技术) 30 30
Design Spec 生成设计文档 10 15
Design Revie 设计复审(和同事审核设计文档) 15 15
Coding Standard 代码规范 10 20
Design 具体设计 30 45
Coding 具体编码 120 240
Code Review 代码复审 10 10
Test 测试(自我测试,修改代码,提交修改) 20 30
Reporting 报告 30 40
Test Report 测试报告 20 20
Size Measurement 计算工作量 5 5
Postmortem & Process Improvement Plan 事后总结,并提出过程改机计划 10 15

8、项目心得

       首先,感受到每个项目的分析阶段特别重要,你的分析缺陷大就意味着你返工的可能性越大。当你对于一个项目的整体思路把握较好后,代码编程时会流畅许多,所以我们一定要养成一个良好的开发习惯。其次,本次项目过程中,感觉特别对不起Java老师,好久没有练习java语言,生疏了许多。这应该就是那句“学如逆水行舟,不进则退”吧。

posted on 2018-03-20 18:23  暖时光lily  阅读(1061)  评论(7编辑  收藏  举报