结对项目

这个作业属于哪个课程 网工194-软件工程
这个作业要求在哪里 完成结对项目四则运算
这个作业的目标 结对完成四则运算命令行程序并进行性能分析

结对成员

  • 王佩之:3219005358
  • 方晓淑:3219005355

一、GitHub

四则运算

二、P2P表格

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

三、效能分析

  • 总体性能预览

  • 内存空间占用统计

    由图可知占用内存最多的是题目的生成、String函数

  • CPU负载情况

四、计算模块接口的设计与实现过程

工程结构

流程图:

1.程序入口类(App.java)
程序的入口,该类主要实现主程序的命令输入和命令提示,生成四则运算表达式。
2.工具类(utilClass.java)
该类为工具类,内部包含各种生成表达式需要使用的函数,如获取随机数,获取随机操作符,获取子表达式,删除括号等等。
3.文件读写类(FileWirter.java)
该类为文件读写类,实现对文件的写入,主要完成对四则运算题目的存储和运算结果的存储。
4.测试类(test.java)
该类为测试类,实现在编码过程中对主要功能的单元测试。

五、关键代码说明

  • 生成运算式的流程代码:利用循环遍历拼接表达式String字符串并判断表达式是否符合要求
 // 开始生成题目,生成num个题目
        for (int i = 0; i < Integer.parseInt(num); i++) {
            hasKuoHaoLeft = false;
            hasKuoHaoRight = false;
            String subject = "";
            System.out.println("第" + (i + 1) + "题:");
            // 第一步,获取该题目的运算符数量
            Random rand = new Random();
            int operatorNum = (int) (rand.nextInt(3)) + 1;
            // 记录加入左括号后是否已经生成操作符,右括号根据此来决定是否需要生成
            boolean temp = false;

            // 第二步,生成题目
            for (int j = 0; j < operatorNum; j++) {

                // 决定是否加入“(”括号
                Random rand1 = new Random();
                if (rand1.nextBoolean() && !hasKuoHaoLeft) {
                    subject = subject + '(';
                    hasKuoHaoLeft = true;
                }

                subject += utilClass.getNum(Integer.parseInt(num2));

                // 决定是否加入“)”括号
                if (hasKuoHaoLeft && !hasKuoHaoRight && temp) {
                    Random rand2 = new Random();
                    if (rand2.nextBoolean()) {
                        subject = subject + ')';
                        hasKuoHaoRight = true;
                    }
                }
                subject += utilClass.getOperate();
                if (hasKuoHaoLeft)
                    temp = true;
            }
            subject += utilClass.getNum(Integer.parseInt(num2));
            // 加入右括号
            if (hasKuoHaoLeft && !hasKuoHaoRight) {
                subject = subject + ')';
            }
            // 至此题目已经拼接完成
            // 去除部分题目开头和结尾为括号的表达式
            System.out.println(utilClass.deleteKuoHao(subject));
            subject = utilClass.deleteKuoHao(subject);
            // 将题目写入文件保存
            FileWirter.wirter((i + 1) + ":" + subject);

            // 开始计算表达式结果
            FileWirter.wirter2((i + 1) + ":" + utilClass.sovleExpretion(subject));
        }
  • 生成txt文件
 /**
     * 写入TXT,覆盖原内容
     *
     * @param content
     * @param fileName
     * @return
     * @throws Exception
     */
    public static boolean writeTxtFile(String content, File fileName) throws Exception {
        RandomAccessFile mm = null;
        boolean flag = false;
        FileOutputStream fileOutputStream = null;
        try {
            fileOutputStream = new FileOutputStream(fileName);
            fileOutputStream.write(content.getBytes("gbk"));
            fileOutputStream.close();
            flag = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return flag;
    }

    /**
     * 写入TXT,追加写入
     *
     * @param filePath
     * @param content
     */
    public static void fileChaseFW(String filePath, String content) {
        try {
            // 构造函数中的第二个参数true表示以追加形式写文件
            FileWriter fw = new FileWriter(filePath, true);

            fw.write(content+"\r\n");
            fw.close();
        } catch (IOException e) {
            System.out.println("文件写入失败!" + e);
        }
    }

    public static void wirter(String args) throws Exception {
        File file = new File(filePath);
        createFile(file);
        //readTxtFile(file);
        // writeTxtFile("我是写入的内容11",file);
        fileChaseFW(filePath, args);
    }
    public static void wirter2(String args) throws Exception {
        File file = new File(filePath2);
        createFile(file);
        //readTxtFile(file);
        // writeTxtFile("我是写入的内容11",file);
        fileChaseFW(filePath2, args);
    }
  • 带括号的表达式算法

计算表达式结果与运算代码

六、测试运行

生成10000道四则运算题目

生成10道四则运算

题目与答案文件

七、项目小结

1.问题及解决方法
本次四则运算项目编写的难点之一在于表达式括号的随机插入和对String类型的表达式进行分解,讲操作数和运算符进行运算。其中遇到的最大问题在于如何对各种类型的操作数进行运算,最后的方案实现为通过将表达式中的自然数,真分数,带分数均转换为带有分母的分数形式来使表达式带有统一特征,运算方式为对各种操作符实现分数的运算算法,并将最后结果进行约分得出答案。一开使用int型无法存储超过32767数的分母,导致程序无法运行,最后用JAVA long类型解决该问题。
2.结对感受

  • 这个结对项目总体用时较长,开始看起来比较简单,但真正开始动手编写代码,有很多的要求以自己的水平还难以达到,所以会在网上查询一些类似的案例和资料进行一些借鉴,尽管如此,也只是完成了这个项目中的基本要求,需求9答案的正确错误统计还在完善中目前实现还有一点出错。此外,由于这次项目是双人合作,跟以往的单人实验有比较大的不同, 双方的思维方式不同,代码水平不同,编码习惯不同,在合作过程中,需要更注重双方的交流,尽管会产生不同的问题,但两个人的想法 给项目带来更多的可能性。总体体验还不错。
  • 本次结对晓淑在合作过程中,给予了我很多技术上的帮助,而我更适合在其他方面进行配合,两个人各有所长,互补其短,这次合作还是很愉快。佩之在项目完成过程中给我提供了很多鼓励和资料,让我们这次作业得以顺利完成,虽然最后没有完全全部需求,但是两个人做事起来多了一份趣味,我也感受到了佩之做事的负责与认真,体验很好。
posted @ 2021-10-26 00:23  F日尧  阅读(47)  评论(0)    收藏  举报