四则运算题目自动生成程序

四则运算表达式生成器

一.github地址

https://github.com/HTwo2O/ArithmeticCalculator

项目参与者: 罗泉水 3118005101 陈鸿畅 3118005087


二.PSP表格(预期)

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 30
Estimate 估计这个任务需要多少时间 30
Development 开发 13
Analysis 需求分析 (包括学习新技术) 60
Design Spec 生成设计文档 0
Design Review 设计复审 (和同事审核设计文档) 0
Coding Standard 代码规范 (为目前的开发制定合适的规范) 10
Design 具体设计 180
Coding 具体编码 1000
Code Review 代码复审 30
Test 测试(自我测试,修改代码,提交修改) 30
Reporting 报告 120
Test Report 测试报告 60
Size Measurement 计算工作量 30
Postmortem & Process Improvement Plan 事后总结, 并提出过程改进计划 30
总计 1460

三.性能测试

  • 分析:字符数组和字符串数据占用了大量的内存。对象的实例化多,耦合性很大。

四.设计实现过程

  • 编程语言

    JAVA

  • 解题思路

    • 主函数引导用户输入创建题目的条件。
    • 主函数实例化ArithmeticGen类(四则运算获得方法),以获得四则运算题目。
    • ArithmeticGen中实例化Expression(表达式实体类),获得用户想要个数的算术表达式。
    • Expression中由Fraction(分数实体类)构成,关于分数的操作放在FractionUtil(分数操作工具类)中。
    • ArithmeticGen获得很多的Expression(表达式)后,通过FileUtil(文件IO工具类)将题目和答案打印在文件中。
    • 用户在题目文件输入答案后,通过Correcting(批改类)批改答案,并将答题情况打印在文件中。
  • 项目结构

    • Entity实体类
      • Expression算术表达式实体类
      • Fraction分数实体类
    • Service服务类
      • ArithmeticGen创建四则运算题目服务类
      • Correcting批改答案服务类
    • Util工具类
      • FileUtil文件工具类
      • Fraction分数工具类
    • 主函数main

五.关键代码

  • 主函数主要部分

            ArithmeticGen Gen = new ArithmeticGen(numRange);
            TwoTuple<String,String> twoTuple = Gen.expBuilder(expAmount);
            FileUtil.write("exercise.txt", twoTuple.first);
            FileUtil.write("answer.txt", twoTuple.second);
    
            System.out.println("出题完毕,请在题目文件中输入您的答案并保存文件");
            System.out.println();
            System.out.println("完成答题后,输入1批改答案,输入其他退出程序");
    
            Scanner scanner = new Scanner(System.in);
            if(scanner.nextLine().equals("1")){
                try {
                    Correcting.correctAnswer();
                    System.out.println("批改完成,请在“Grade.txt”文件中查看答题情况");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }else {
                System.exit(0);
            }
    
  • ArithmeticGen类中创建多条表达式的方法

	 public TwoTuple<String,String> expBuilder(int expAmount) {
		 StringBuilder exptext = new StringBuilder();
		 StringBuilder anstext = new StringBuilder();
		 for(int i=1; i<=expAmount; i++) {
			 Expression expBean = new Expression();

			 int optNum = random.nextInt(3)+1;
			 for(int n = 0; n < optNum; n++){
				 expBean=createExp(expBean);
			 }


			 exptext.append("第" + i + "题: " + expBean.getExpression() + "   请作答:"+"\n");

			 anstext.append("第" + i + "题: " + expBean.getFraction() + "\n");
		 }
		 return tuple(exptext.toString(), anstext.toString());
	 }
  • 创造一条表达式的方法

    	 private Expression createExp(Expression expBean1) {
    		 Expression expBean=new Expression();
    	    	Boolean flagZero = false;
    	    	Fraction f2= FractionUtil.CreatFraction(num);
    
    	    	//随机设置f2自然数
    	    	if(random.nextBoolean()){
    				f2.setDenominator(1);
    			}
    	        char opt = '+';
    	        switch(random.nextInt(4))  {
    	            case 0 : opt = '+';    break;
    	            case 1 : opt = '-';    break;
    	            case 2 : opt = '*';    break;
    	            case 3 : opt = '÷';    break;
    
    	            default: break;
    	        };
    	       
    	        if((expBean1.getExpression()).equals("")) {
    	        	Fraction f1= FractionUtil.CreatFraction(num);
    	        	if(f2.getNumerator()==0&&opt=='÷')
    	        		opt = '+';
    	        	if(!f1.greater(f2)&&opt=='-') {
    	        		expBean.setExpression( "" + f2 + opt + f1);
    		        	expBean.setFraction(FractionUtil.calculate(f2, f1, opt));
    	        	}else {
    	        		expBean.setExpression( "" + f1 + opt + f2);
    		        	expBean.setFraction(FractionUtil.calculate(f1, f2, opt));
    	        	}
    	        	
    	        }else {
    	        	if(random.nextBoolean()) {
    	        		if(f2.getNumerator()==0&&opt=='÷')
    		        		opt = '+';
    	        		if(!expBean1.getFraction().greater(f2)&&opt=='-') {
    	        			expBean.setExpression("" + f2 + opt + "(" + expBean1 + ")");
    		        		expBean.setFraction(FractionUtil.calculate(f2, expBean1.getFraction(), opt));
    	        		}else {
    	        			expBean.setExpression( "(" + expBean1 + ")" + opt + f2);
    		        		expBean.setFraction(FractionUtil.calculate(expBean1.getFraction(), f2, opt));
    	        		}
    
    	        	}else {
    	        		if(expBean1.getFraction().getNumerator()==0&&opt=='÷')
    	        			opt = '+';
    	        		if(expBean1.getFraction().greater(f2)&&opt=='-') {
    	        			expBean.setExpression( "(" + expBean1 + ")" + opt + f2);
    		        		expBean.setFraction(FractionUtil.calculate(expBean1.getFraction(), f2, opt));
    	        		}else {
    	            		expBean.setExpression("" + f2 + opt + "(" + expBean1 + ")");
    		        		expBean.setFraction(FractionUtil.calculate(f2, expBean1.getFraction(), opt));
    	        		}
    	
    	        	}
    	        }
    	        return expBean;
    	    }`
    
  • 批改答案方法correctAnswer()

    public static void correctAnswer() throws Exception{
            String lineAns;
            String lineExe;
            int test = 1;
            ArrayList<Integer> listCorrect = new ArrayList<>();
            ArrayList<Integer> listWrong = new ArrayList<>();
    
            BufferedReader brExe = new BufferedReader(new FileReader("exercise.txt"));
            BufferedReader brAns = new BufferedReader(new FileReader("answer.txt"));
            //BufferedWriter bw = new BufferedWriter(new FileWriter("Grade.txt"));
            PrintStream bw = new PrintStream(new FileOutputStream("Grade.txt"));
            while ((lineAns = brAns.readLine()) != null){
                lineAns = lineAns.split(" ")[1];
    
                lineExe = brExe.readLine();
                String [] exerSplit = lineExe.split(":");
                if(exerSplit.length == 3){
                    lineExe = exerSplit[2];
                }
    
                if(lineAns.equals(lineExe)){
                    listCorrect.add(test++);
                }else {
                    listWrong.add(test++);
                }
            }
    
    
            bw.print("Correct:" + listCorrect.size() + "(");
            if(listCorrect.size() == 0){
                bw.print(")");
            }else{
                for(int i = 0; i < listCorrect.size(); i++){
                    bw.print(listCorrect.get(i));
                    if(i == listCorrect.size()-1){
                        bw.print(")");
                    }else {
                        bw.print(",");
                    }
                }
            }
    
    
            bw.println();
            bw.print("Wrong:" + listWrong.size() + "(");
            if(listWrong.size() == 0){
                bw.print(")");
            }else {
                for (int i = 0; i < listWrong.size(); i++) {
                    bw.print(listWrong.get(i));
                    if (i == listWrong.size() - 1) {
                        bw.print(")");
                    } else {
                        bw.print(",");
                    }
                }
            }
    
            bw.close();
            brAns.close();
            brExe.close();
    
        }
    

六.功能测试

  • 测试一

    • exercise.txt

    • answer.txt

    • Grade.txt

  • 测试二

    • exercise.txt

    • answer.txt

    • Grade.txt

  • 测试三

    • exercise.txt

    • answer.txt

    • Grade.txt

  • 测试四

    • exercise.txt

    • answer.txt

    • Grade.txt

七.PSP表格(完成)

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 30 15
Estimate 估计这个任务需要多少时间 30 15
Development 开发 1310 1410
Analysis 需求分析 (包括学习新技术) 60 100
Design Spec 生成设计文档 0 0
Design Review 设计复审 (和同事审核设计文档) 0 0
Coding Standard 代码规范 (为目前的开发制定合适的规范) 10 30
Design 具体设计 180 210
Coding 具体编码 1000 1020
Code Review 代码复审 30 30
Test 测试(自我测试,修改代码,提交修改) 30 20
Reporting 报告 120 145
Test Report 测试报告 60 120
Size Measurement 计算工作量 30 10
Postmortem & Process Improvement Plan 事后总结, 并提出过程改进计划 30 15
总计 1460 1570

八.总结

  • 一定要规范。命名规范、分包规范、结构规范。
  • 和他人合作一定要及时讨论好,多交流多沟通。
  • 熟能生巧。打码少了,知识点就生疏了;生疏了,效率便会很低。
posted @ 2020-03-31 23:56  HTwo2O  阅读(285)  评论(0编辑  收藏  举报