结对作业

结对项目

这个作业属于哪个课程 https://edu.cnblogs.com/campus/gdgy/InformationSecurity1912-Softwareengineering
这个作业要求在哪里 https://edu.cnblogs.com/campus/gdgy/InformationSecurity1912-Softwareengineering/homework/12147
这个作业的目标 尝试与同伴一起合作完成项目,学习了解团队合作的方式

一.小组成员信息

姓名 邓盛永 王嘉杰
学号 3119005456 3119005474
Github项目地址 https://github.com/Dengsy0516/fourRule.git https://github.com/Jaywilde/3119005474/tree/main/ArithmeticOperations

仓库截图

邓盛永

王嘉杰

二.PSP表格

PSP是卡耐基梅隆大学(CMU)的专家们针对软件工程师所提出的一套模型:Personal Software Process (PSP, 个人开发流程,或称个体软件过程)。

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 60 90
Estimate 估计这个任务需要多少时间 20 25
Development 开发 600 800
Analysis 需求分析(包括学习新技术) 80 100
Design Spec 生成设计文档 40 45
Design Review 设计复审 30 35
Coding Standard 代码规范(为目前的开发制定合适的规范) 15 13
Design 具体设计 90 75
Coding 具体代码 800 850
Code Review 代码复审 50 65
Test 测试(自我测试,修改代码,提交修改) 20 20
Reporting 报告 120 140
Test Repor 测试报告 30 50
Size Measurement 计算工作量 20 20
Postmortem & Process Improvement Plan 事后总结,并提出过程改进计划 60 45
合计 2035 2373

三.效能分析



四.设计实现过程

1.需求分析

(1)使用 -n 参数控制生成题目的个数

(2)使用 -r 参数控制题目中数值(自然数、真分数和真分数分母)的范围

(3)生成的题目中计算过程不能产生负数

(4)生成的题目中如果存在形如e1÷ e2的子表达式,那么其结果应是真分数

(5)每道题目中出现的运算符个数不超过3个

(6)程序一次运行生成的题目不能重复

(7)生成的题目存入执行程序的当前目录下的Exercises.txt文件

(8)在生成题目的同时,计算出所有题目的答案,并存入执行程序的当前目录下的Answers.txt文件

(9)程序应能支持一万道题目的生成

2.类说明

(1)AirthmeticMain

主方法,用于调用Utils包内的各种类

(2)CalculateRule

定义四则运算的规则

(3)CalculationsChangeUtils

用于将中缀表达式转换成后缀表达式

(4)ExpressionIOUtils

用于文件的读取和写入

(5)Fraction

用于定义分数类型的数值

(6)OperationValue

用于定义四则运算符的优先级

(7)RandomUtils

用于生成符合要求的随机数

(8)RepealtCheck

用于检测是否生成相同的四则运算式

3.类关系

五.代码说明

1.随机数生成

在随机数类中,我们设置了多个随机数,分别包含有不同功能,例如在此处,我们通过为四则运算符加权,通过产生的随机数来决定下一个位置应该放置哪一个运算符。但是在加权的时候,原本我们打算通过生成装有对应ASCII码的集合中的数值来生成相应的运算符,结果发现÷找不到对应的ASCII码,如果使用\的话也会和分数混淆,最终我们并未采用这种生成方式,转而直接加权1-4。
public static String OpChooseRandom(){
    int choose_ran = (int)(Math.random()*(4-1+1)+1);
    String operate;
    if (choose_ran == 1){operate = "+";}
    else if(choose_ran == 2){operate = "-";}
    else if(choose_ran == 3){operate = "×";}
    else {operate = "÷";}
    return operate;
}

2.算式生成

我们采用了三个if的方式,通过判断随机数OperateNumber(生成运算符个数)来决定每次生成的是几元运算式。比如:OperateNumber=2的时候,我们生成的是三元一次计算式。然后再通过字符串的拼接生成表达式并输出。
我们通过mark标记该类计算式生成的个数,mark经过计算转化最终可以作为查重数组的下标使用。
        if (OperateNumber == 2) {
            Fraction Value1 = RandomUtils.FractionRandom(ValueRange);   
            String OpChoose1 = RandomUtils.OpChooseRandom();  
            Fraction Value2 = RandomUtils.FractionRandom(ValueRange);
            String OpChoose2 = RandomUtils.OpChooseRandom();
            Fraction Value3 = RandomUtils.FractionRandom(ValueRange);
            mark2 = mark2 + 1;
            String Expression2 = Value1 + OpChoose1 + Value2 + OpChoose2 + Value3;
            System.out.println(Expression2 + "=");
            String PolishExpression2 = CalculationsChangeUtils.ExpressionChange(Expression2, stack);
            RepeatCheck.Check(QuestionNumber, mark2, PolishExpressionSave2, QuestionSave2, PolishExpression2, Expression2);
            PolishExpression2 = PolishExpression2.replace("[", "");
            PolishExpression2 = PolishExpression2.replace(" ", "");
            PolishExpression2 = PolishExpression2.replace("]", "");
            List<String> list = Arrays.asList(PolishExpression2.split(","));
            for (int k = 0; k < list.size(); k++) {
                get[k] = list.get(k);
                stack.push(get[k]);
            }
            String result = CalculationsChangeUtils.doCalculation(stack);
            KeySave2[mark2] = result;
            System.out.println(KeySave2[mark2]);
        }
在编写本段代码的时候我们踩了一个大坑,原本我们用List来储存字符串,但通过遍历字符串运算题目答案的时候总是有误。
debug我们会发现无法识别+-×÷符号,并且输出格式不规范。比如说中缀表达式:1\2÷5+2,当转换为后缀表达式的时候应该为1/2,5,÷,2,+;但实际上输出的是[1/2, 5, ÷, 2, +]。
经过多处资料查证,最后发现当直接使用print语句打印List的时候,逆波兰式会被[]括起来,并且在每一个逗号后都会添加一个空白字符。这对于我们后续遍历逆波兰式进行运算时造成了极大的困扰。
            PolishExpression2 = PolishExpression2.replace("[", "");
            PolishExpression2 = PolishExpression2.replace(" ", "");
            PolishExpression2 = PolishExpression2.replace("]", "");
通过以上语句,我们最终将不想要的字符转换为NULL,实现了删除的功能。

3.算式查重

此处我们通过数组存入已经生成并经过重复检验的逆波兰式,然后在每一个新逆波兰式生成时,再次与数组内部的式子进行循环检验,最终我们可以获得不重复的四则运算式。
public static void Check(int QuestionNumber, int mark, String[] PolishExpressionSave, String[] QuestionSave, String PolishExpression,String Expression){
    for(int k=0;k<QuestionNumber;k++){
        if(PolishExpressionSave[k] == null){
            QuestionSave[mark] = Expression;
            PolishExpressionSave[mark] = PolishExpression;
        } else if(PolishExpressionSave[k].equals(PolishExpression)){
            mark=mark-1;
        }else{
            QuestionSave[mark] = Expression;
            PolishExpressionSave[mark] = PolishExpression;
        }
    }
}

六.测试运行

七.项目小结

1.结对感受

邓盛永:在本次项目中,我领悟到了团队合作的优势,也学会了如何利用合作来加快我们完成项目的进度,于此同时,在本次项目中也发现了自己在代码能力上的不足,有思路但无法通过代码实现,只是我往后需要努力的方向
王嘉杰:在本次结对项目中,我体会到了结对合作的好处:思维的碰撞能够给予彼此非常多的灵感,并且在交流的过程中也能够锻炼自己的逻辑能力和表达能力。除去团队合作,我也有发现了自己在代码能力上有非常多的不足之处,Java有很多函数我都不了解,甚至说根本没见过;在完成项目的过程中会犯拖延症,总是无法保证每天都能够完成预期中的量。

2.闪光点或建议分享

邓盛永:本次项目是双人完成,按理来讲应该是会比一个人更容易完成,事实上也确实会更轻松,两个人有更多的想法,有更广的思路,解决同一个问题的方法也更多,但在拥有这些便利的同时,沟通至关重要,如果没有良好的沟通,两个人无法达成一致,将会导致进度的卡壳,幸运的事我与嘉杰组队,在有分歧的时候我们都能耐心地与对方分享,所以我们的进度顺利且迅速。
王嘉杰:在一起思考代码逻辑的时候,盛永给我了非常多的灵感,并且在我逻辑出现问题的时候,能够非常快速且清晰地向我指出我的不足之处。搭档拥有比我更加灵活的思维方式,并且在代码写作上具有极佳的大局观,非常值得我好好学习。希望的日后的学习打码生涯中能够多多交流,互相学习,共同进步。

posted @ 2021-10-26 00:33  Corilde  阅读(51)  评论(0编辑  收藏  举报