第一次软工导论作业(四则运算)

第一次软工导论作业(四则运算)

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计划52
Estimate 估计这个任务需要多少时间,并规划大致工作步骤52
Development开发3326
Analysis需求分析 (包括学习新技术)13
Design Spec生成设计文档20
Design Review设计复审 (和同事审核设计文档)10
Coding Standard代码规范 (为目前的开发制定合适的规范)11
Design具体设计21
Coding 具体编码2015
Code Review 代码复审 11
Test 测试(自我测试,修改代码,提交修改)55
Reporting 报告35
Test Report 测试报告 0.50.5
Size Measurement 计算工作量 0.50.5
Postmortem & Process Improvement Plan 事后总结, 并提出过程改进计划 24
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值