第一次软工导论作业(四则运算)
Coding.net仓库地址:https://git.dev.tencent.com/DYKHIMY/OperationalExercises.git
GitHub仓库地址:https://github.com/DYKHIMY/OperationalExercises.git
一、需求分析
1、接收一个输入参数n,随机产生n道四则运算练习题,符号用±*÷来表示。
2、每个数字在 0 和 100 之间。
3、运算符在3个到5个之间并且每道练习题至少要包含2种运算符。
4、运算过程中不得出现负数与非整数。
5、将学号和生成的练习题及对应答案输出到文件“result.txt”中,不输出额外信息。
6、附加需求:
产生带括号的四则运算并求解,算式中存在的括号必须大于2个,且不得超过运算符的个数。
产生真分数的加减法运算,运算过程中都为最简真分数。
二、功能设计
能够根据用户输入的参数n随机产生n道符合要求的练习题,自动算出答案,并将式子与答案以文档的形式呈现。
三、设计实现
这个程序一共只有两个类:Main和Exercise类
该程序的整体流程:
main方法接受控制台输入的题目数量n,然后循环n次Exercises类中的两个方法,这两个方法运行一次输出一道运算题到result.txt文件中。
至于输出到文件,当输入题目数n时,main方法会先将我的学号输出到文件result.txt中,覆盖之前的内容,调用Exercsies类的setExercises()方法,每次会输出一道题到文件中,但不会覆盖之前的内容。
Main类只包含一个main方法:
Exercises类中包含两个方法:
setExercise()和 setExercisesNum(),前者输出一道运算题到文件中,后者设置该函数的循环次数。
四、算法实现
算法我是用java数组来实现的,先创建两个用来显示运算符和数字的数组viewope[]和viewnum[],两个用来运算的运算符和数字数组operator[]和nums[],两个用来计算加减的运算符和数字数组calope[]和calnum[];
然后随机出运算符和数字分别放入前四个数组,然后开始遍历运算符,如果遍历到加减号就将符号和符号前的一个数字放入calope[]和calnum[],如果遍历到乘除号则先检验除号是否合理,若不合理则重新随机除号右边的数字,然后计算乘除号两边的数字并将结果放入右边数字所在的位置;
随机完了之后,计算最后的加减法,也就是calope[]和calnum[]中的符号和数字,这里需要做一个减法的检验,若是出现负数则需要重新随机,因为时间原因,封装的函数比较少,很多计算都是堆积在一个函数中,代码耦合性太高,所以这里对减法的检验只能重新调用自身函数,重新随机一道运算题。
五、测试运行
六、代码展示
这里只展示主要算法部分,源代码已上传到github、腾讯云。
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
// Created by IntelliJ IDEA.
//User: lhz
//Date: 2019/3/13
//Time: 19:24
//To change this template use File | Settings | File Templates.
public class Exercises {
int flag=0;
public void setExercise() throws IOException {
int opNum = (int) (Math.random() * 3) + 3;//运算符个数(3,4,5)
int[] nums = new int[opNum + 1];//用来运算
int[] viewnum = new int[opNum + 1];//用来显示
for (int i = 0; i < opNum + 1; i++) {
nums[i] = (int) (Math.random() * 100);
viewnum[i] = nums[i];
}//为参与运算的数字赋值
char[] chars = {'+', '-', '*', '÷'};
int[] operator = new int[opNum];//用来运算
char[] viewope = new char[opNum];//用来显示
//先计算加减
//新建两个数组,分别放算完乘除后的数字和运算符
int[] calnum = new int[opNum + 1];
int[] calope = new int[opNum];
int cn = 0;
int co = 0;
for (int i = 0; i < opNum; i++) {
operator[i] = (int) (Math.random() * 4);//随机出运算符
if (operator[i] == 0 || operator[i] == 1) {
calnum[cn] = nums[i];
calope[co] = operator[i];
cn++;
co++;
}
if (operator[i] == 2) {
nums[i + 1]= nums[i]*nums[i + 1];
}
if (operator[i] == 3) {
while ((nums[i + 1] == 0)||((nums[i] % nums[i + 1]) != 0) ) {//除号检验是否合理(两个条件的次序不能颠倒)
nums[i + 1] = (int)(Math.random() * 100);
}
viewnum[i + 1] = nums[i + 1];//若不合理需重新为数字赋值,对应的显示用的数组也要更新值
nums[i + 1] =nums[i]/nums[i + 1];
}
viewope[i] = chars[operator[i]];//为字符数组赋对应的符号值
}//为运算符赋值
calnum[cn]=nums[opNum];//最后一个数直接放入计算数组calnum[]
//最后的加减运算
int result=0;
int flag2=0;//假如没有加减运算,cn=0
for (int i=0;i<cn;i++){
flag2=1;
if(i==0){
if (calope[i]==0){
result=calnum[i]+calnum[i + 1];
}
if(calope[i]==1){
if (calnum[i]<calnum[i+1]){
flag=1;
return;
}else{
result=calnum[i]-calnum[i + 1];
}
}
continue;
}
if (calope[i]==0){
result=result+calnum[i + 1];
}
if(calope[i]==1){
if (result<calnum[i+1]){
flag=1;
return;
}
result=result-calnum[i + 1];
}
}
if (flag2==0){
result=calnum[0];
}
//输出最后结果
String ex=new String();
for (int i=0;i<opNum;i++){
ex+=String.valueOf(viewnum[i]);
ex+=String.valueOf(viewope[i]);
}
ex+=String.valueOf(viewnum[opNum]);
ex+="=";
ex+=result;
System.out.println(ex);
ex+="\r\n";//换行
File file = new File("./result.txt");
if (!file.exists())
file.createNewFile();
FileOutputStream fos = new FileOutputStream(file,true);//将题目输出到文件,不覆盖
byte[] bytes = ex.getBytes();
fos.write(bytes);
}
public void setExercisesNum(int n) throws IOException {
for (int i=0;i<n;i++){
this.setExercise();
if (this.flag==1){
i--;
this.flag=0;//成员变量还需变回0
}
}
}
}
七、总结
由于事先并没有做太多准备工作,没有参考更多的算法,想到了一种算法就直接上手去做,另外我也比较头铁,就是不想放弃这种算法,导致最后附加功能比较难加入。另外就是代码的耦合性非常重要,在开发过过程中,代码的耦合性越低越好,这样各个模块之间的相互关联性会更少,在改动一个模块的时候影响到的范围也才会越小,但是如果没有事先进行程序设计,而是上来就开始敲代码,那随着代码的增加,耦合性会越来越高,最后改动起来或是增加功能的时候得修改与之关联的一大堆代码。
</tbody>
PSP2.1 | 任务内容 | 计划共完成需要的时间(h) | 实际完成需要的时间(h) |
---|---|---|---|
Planning | 计划 | 5 | 2 |
Estimate | 估计这个任务需要多少时间,并规划大致工作步骤 | 5 | 2 |
Development | 开发 | 33 | 26 |
Analysis | 需求分析 (包括学习新技术) | 1 | 3 |
Design Spec | 生成设计文档 | 2 | 0 |
Design Review | 设计复审 (和同事审核设计文档) | 1 | 0 |
Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 1 | 1 |
Design | 具体设计 | 2 | 1 |
Coding | 具体编码 | 20 | 15 |
Code Review | 代码复审 | 1 | 1 |
Test | 测试(自我测试,修改代码,提交修改) | 5 | 5 |
Reporting | 报告 | 3 | 5 |
Test Report | 测试报告 | 0.5 | 0.5 |
Size Measurement | 计算工作量 | 0.5 | 0.5 |
Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 2 | 4 |