结对项目

一、结对项目成员

本次项目成员 学号 github仓库
邓丹丹 3219005354 https://github.com/dxadd/dxadd/tree/main/ForCalculate-master
陈静蓓 3219005353 https://github.com/bubble-blase/forcalculate

二、作业要求

作业所属课程 网络工程3班
作业要求在哪里 作业要求
作业目标 实现一个自动生成小学四则运算题目的命令行程序

三、PSP表格

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 30 45
Estimate 估计这个任务需要多少时间 5 5
Development 开发 200 380
Analysis 需求分析 (包括学习新技术) 20 20
Design Spec 生成设计文档 10 10
Design Review 设计复审 5 5
Coding Standard 代码规范 (为目前的开发制定合适的规范) 20 30
Design 具体设计 20 30
Coding 具体编码 250 280
Code Review 代码复审 30 20
Reporting 报告 10 10
Test Repor 测试报告 20 30
Size Measurement 计算工作量 20 25
Postmortem & Process Improvement Plan 事后总结, 并提出过程改进计划 15 20
Total 合计 655 910

效能分析

这就是项目启动过程中cpu,内存等各个方面的性能指标。
结对项目

设计过程

1、设计思路

考虑到分数的实现,因为java不存在可以处理分数运算的类,所以应将整数与分数作为一个对象来处理,即整数就是分母为1的分数。也因此做了实体类Fraction

受到Fraction启发,做了实体类OperationExpression,它的属性包含了表达式及其答案

题目生成设计思路:

于是就可以实例化一个OperationExpression对象e,运用getExpression类的getExp方法生成一个表达式设置为e的表达式,getExp()方法中调用了CalculateService的calculate()计算方法得到答案设置为e的答案。calculate()方法中产生了负数则会返回空值,可根据这个空值判断表达式是否存在负数,若存在则丢弃重新生成。其后,还会经过DuplicateCheck类的查重。通过上述步骤,即可生成一道题目。

2、设计的流程图

生成题目流程图
结对项目

​ 算术表达式中序变后序流程图
结对项目

3、设计项目结构

实体类:分数类Fraction,算术表达式类OperationExpression

工具类:查重类DuplicateCheck

服务类:计算类CalculateService,答案判错类CheckService,表达式生成类getExpression

项目入口:OperationPro
结对项目

关键代码说明

测试代码

点击查看代码
![](https://www.icode9.com/i/l/?n=20&i=blog/2531492/202110/2531492-20211026002042583-786735412.png)
import bean.Fraction;
import bean.OperationExpression;
import org.junit.Test;

import java.util.List;

public class test {
    @Test
    public void test1(){
        OperationPro.mainGenerate(10,10000);
    }
    @Test
    public void test2(){
        OperationPro.mainCheck("D:\\abc\\ForCalculate\\Answer1.txt","D:\\abc\\ForCalculate\\Answer.txt");
    }
    @Test
    public void test3(){
        getExpression getExpression = new getExpression();
        List exp = getExpression.getExp(new OperationExpression(null, null, null), 10);
        System.out.println(exp);
    }
    @Test
    public void test4(){
        getExpression getExpression = new getExpression();
        List exp = getExpression.getExp(new OperationExpression(null, null, null), 3);
        System.out.println(exp);
    }
    @Test
    public void test5(){
        Fraction a = new Fraction(true,10);
        Fraction b = new Fraction(true,10);
        System.out.println(a.sub(b));
    }
    @Test
    public void test6(){
        Fraction a = new Fraction(false,20);
        Fraction b = new Fraction(true,10);
        System.out.println(a.div(b));
    }
    @Test
    public void test7(){
        Fraction a = new Fraction(false,10);
        Fraction b = new Fraction(false,10);
        System.out.println(a.add(b));
    }
    @Test
    public void test8(){
        Fraction a = new Fraction(false,10);
        Fraction b = new Fraction(false,10);
        System.out.println(a.sub(b));
    }
    @Test
    public void test9(){
        System.out.println(CalculateService.prior("+", "-"));
    }
    @Test
    public void test10(){
        getExpression getExpression = new getExpression();
        List exp = getExpression.getExp(new OperationExpression(null, null, null), 3);
        System.out.println(CalculateService.toPostFix(exp));
    }
}

1.表达式生成类getExpression
点击查看代码
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

import bean.Fraction;
import bean.OperationExpression;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class getExpression {
    private static Random r = new Random();
    static List l = new ArrayList();

    public getExpression() {
    }

    public List getExp(OperationExpression e, int limit) {
        Fraction f1 = new Fraction(r.nextBoolean(), limit);
        List stringList = new ArrayList();
        List l = new ArrayList();
        l.add(f1);
        stringList.add(f1.toString());
        int a = r.nextInt(3);

        do {
            express(e, l, stringList, limit);
            --a;
        } while(a >= 0);

        Fraction f = CalculateService.calculate(l);
        if (f == null) {
            return null;
        } else {
            e.setRes(f);
            e.setStringList(stringList);
            return stringList;
        }
    }

    static void express(OperationExpression e, List l, List stringList, int limit) {
        Fraction f = new Fraction(r.nextBoolean(), limit);
        int a = r.nextInt(4);
        switch(a) {
        case 0:
            l.add("+");
            l.add(f);
            stringList.add("+");
            stringList.add(f.toString());
            break;
        case 1:
            l.add("-");
            l.add(f);
            stringList.add("-");
            stringList.add(f.toString());
            break;
        case 2:
            l.add("×");
            l.add(f);
            stringList.add("×");
            stringList.add(f.toString());
            break;
        case 3:
            l.add("÷");
            l.add(f);
            stringList.add("÷");
            stringList.add(f.toString());
            break;
        default:
            System.out.println("出错");
        }

        e.setList(l);
    }
}

2.计算类CalculateService
点击查看代码
import bean.Fraction;
import java.util.Iterator;
import java.util.List;
import java.util.Stack;

public class CalculateService {
    public CalculateService() {
    }

    public static Stack toPostFix(List list) {
        Stack number = new Stack();
        Stack<String> action = new Stack();
        int symble = false;
        Iterator var4 = list.iterator();

        while(true) {
            String temp;
            while(var4.hasNext()) {
                Object o = var4.next();
                int symble = flag(o, number, action);
                switch(symble) {
                case 1:
                    number.push(o);
                    break;
                case 2:
                    action.push((String)o);
                    break;
                case 3:
                    action.push((String)o);
                    break;
                case 4:
                    while(!action.empty() && action.peek() != "(" && !prior((String)o, (String)action.peek())) {
                        number.push(action.pop());
                    }

                    action.push((String)o);
                    break;
                case 5:
                    action.push((String)o);
                    break;
                case 6:
                    while(!action.isEmpty()) {
                        temp = (String)action.pop();
                        if (temp.equals("(")) {
                            break;
                        }

                        number.push(temp);
                    }
                }
            }

            Stack temp = new Stack();
            Iterator var9 = action.iterator();

            while(var9.hasNext()) {
                temp = (String)var9.next();
                number.push(temp);
            }

            var9 = number.iterator();

            while(var9.hasNext()) {
                Object o = var9.next();
                temp.push(o);
            }

            return temp;
        }
    }

    public static int flag(Object o, Stack number, Stack<String> action) {
        if (o instanceof Fraction) {
            return 1;
        } else {
            String s = (String)o;
            if (s.matches("(\\+)|(\\-)|(\\×)|(\\÷)")) {
                if (action.isEmpty()) {
                    return 2;
                } else {
                    return prior(s, (String)action.peek()) ? 3 : 4;
                }
            } else if (s.matches("\\(")) {
                return 5;
            } else {
                return s.matches("\\)") ? 6 : 0;
            }
        }
    }

    public static Boolean prior(String s1, String s2) {
        if (s2.matches("\\(")) {
            return true;
        } else {
            return s1.matches("(\\×)|(\\÷)") && s2.matches("(\\+)|(\\-)") ? true : false;
        }
    }

    public static Fraction calculate(List list) {
        Stack stack = toPostFix(list);
        Stack<Fraction> newStack = new Stack();
        Iterator var3 = stack.iterator();

        while(true) {
            if (var3.hasNext()) {
                Object o = var3.next();
                if (o instanceof Fraction) {
                    newStack.push((Fraction)o);
                    continue;
                }

                if (newStack.size() >= 2) {
                    Fraction a = (Fraction)newStack.pop();
                    Fraction b = (Fraction)newStack.pop();
                    String var7 = (String)o;
                    byte var8 = -1;
                    switch(var7.hashCode()) {
                    case 43:
                        if (var7.equals("+")) {
                            var8 = 0;
                        }
                        break;
                    case 45:
                        if (var7.equals("-")) {
                            var8 = 1;
                        }
                        break;
                    case 215:
                        if (var7.equals("×")) {
                            var8 = 2;
                        }
                        break;
                    case 247:
                        if (var7.equals("÷")) {
                            var8 = 3;
                        }
                    }

                    switch(var8) {
                    case 0:
                        newStack.push(b.add(a));
                        continue;
                    case 1:
                        Fraction fraction = b.sub(a);
                        if (fraction.getNominator() > 0 && fraction.getDenominator() > 0) {
                            newStack.push(fraction);
                            continue;
                        }

                        return null;
                    case 2:
                        newStack.push(b.muti(a));
                        continue;
                    case 3:
                        newStack.push(b.div(a));
                    default:
                        continue;
                    }
                }
            }

            return (Fraction)newStack.pop();
        }
    }
}

3.查重类DuplicateCheck

点击查看代码
package utils;

import java.util.Iterator;
import java.util.List;

public class DuplicateCheck {
    public DuplicateCheck() {
    }

    public boolean DuCheck(List l, List allList) {
        Iterator it = allList.iterator();

        List L;
        do {
            if (!it.hasNext()) {
                return false;
            }

            L = (List)it.next();
        } while(!this.CheckList(l, L));

        return true;
    }

    boolean CheckList(List l1, List l2) {
        if (l1 == l2) {
            return true;
        } else if (l1 == null && l2 == null) {
            return true;
        } else if (l1 != null && l2 != null) {
            if (l1.size() != l2.size()) {
                return false;
            } else {
                return l1.containsAll(l2) && l2.containsAll(l1);
            }
        } else {
            return false;
        }
    }
}

4.答案判错类CheckService

点击查看代码
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;

public class CheckService {
    public CheckService() {
    }

    public static Map<String, String> Check(String checked, String answer) throws IOException {
        Map<String, String> m = new HashMap();
        String error = "";
        String correct = "";
        int errornum = 0;
        int correctnum = 0;
        String str1 = "";
        String str2 = "";
        File checkedfile = new File(checked);
        FileInputStream input1 = new FileInputStream(checkedfile);
        BufferedReader reader1 = new BufferedReader(new InputStreamReader(input1));
        File answerfile = new File(answer);
        FileInputStream input2 = new FileInputStream(answerfile);
        BufferedReader reader2 = new BufferedReader(new InputStreamReader(input2));

        while((str1 = reader1.readLine()) != null && (str2 = reader2.readLine()) != null) {
            String[] str;
            if (!str1.trim().equals(str2.trim())) {
                str = str1.split("\\.");
                error = error + str[0] + ",";
                ++errornum;
            } else {
                str = str1.split("\\.");
                correct = correct + str[0] + ",";
                ++correctnum;
            }
        }

        if (error.equals("")) {
            error = "Wrong: " + errornum + "";
        } else {
            error = "Wrong: " + errornum + "(" + error.substring(0, error.length() - 1) + ")";
        }

        if (correct.equals("")) {
            correct = "Correct: " + correctnum + "";
        } else {
            correct = "Correct: " + correctnum + "(" + correct.substring(0, correct.length() - 1) + ")";
        }

        m.put("wrong", error);
        m.put("correct", correct);
        return m;
    }
}

运行结果
结对项目

项目小结

在这一次的协同合作项目交流中,一开始我们就各自做自己的,没有交流,等我们汇总的时候才发现又很多问题。交流过后,我们不断磨合,不断测试代码,思考代码可行性,最后就在对方身上学到了很多东西。我们在设计过程中,取长补短,发挥各自的优势,一个人主要负责代码方面的问题,另一个负责测试相关的数据,总体合作下来感受到了团队合作的重要性,也因为后期的合作才能最终完成项目。

上一篇:【递归】分数求和


下一篇:【python标准库】数字和数学模块精心整理