软工第二次作业——熟悉使用工具

GIT地址我的GITHUB地址
GIT用户名NyimaC
学号后五位61111
博客地址我的博客地址
作业链接链接

Part1.环境配置

因为之前已经用JAVA写过程序,所以环境是已经配好了的,在此没有遇到太大的问题。
JAVA版本是JAVA8.0 编译器使用的是IDEA

1784271-20190917212454177-471224629.png

1784271-20190917212503373-1619382844.png

1784271-20190917212513079-838078249.png


Part2.代码编写

编码题目:

阿超家里的孩子上小学一年级了,这个暑假老师给家长们布置了一个作业:家长每天要给孩子出一些合理的,但要有些难度的四则运算题目,并且家长要对孩子的作业打分记录。

作为程序员的阿超心想,既然每天都需要出题,那何不做一个可以自动生成小学四则运算题目与解决题目的命令行 “软件”呢。他把老师的话翻译一下,就形成了这个软件的需求:

程序接收一个命令行参数 n,然后随机产生 n 道加减乘除(分别使用符号+-*/来表示)练习题,每个数字在 0 和 100 之间,运算符在 2 个 到 3 个之间。

由于阿超的孩子才上一年级,并不知道分数。所以软件所出的练习题在运算过程中不得出现非整数,比如不能出现 3÷5+2=2.6 这样的算式。

练习题生成好后,将生成的 n 道练习题及其对应的正确答案输出到一个文件 subject.txt 中。

使用语言:JAVA

与题目不同的地方的声明:

1、运算符存在差异。题目上的是(+-*/) 我的是(+-×÷)

2、我的文件名为“题目.txt”

编码思路:

思维导图:

1784271-20190918162000122-476519861.png

代码部分(主要部分):

"Talk is cheap. Show me the code."

结构

1784271-20190917212539398-1564820486.png

生成题目的类

public class FormulaMakerTest {
/**
 * 生成题目的类
 */

public LinkedList<String> questionMaker(int total)
{
    //用于存放生成的运算式
    String[] formulas = new String[total];
    LinkedList<String> questionList = new LinkedList<>();
    Numbers numbers = new Numbers();
    OperationImpl operation = new OperationImpl();
    OperationStringImpl operationString = new OperationStringImpl();

    //循环开始的参数(一个用于外循环,一个用于循环)
    int start1;
    int start2;
    //用于保存每次运算的结果
    int result;
    //用于标识运算是否会出现小数
    int judge = 0;
    for(start1=0; start1<total; start1++) {
        //标识结果集的下标
        //生成随2~3个的运算符
        numbers.operationNumber = (int)(2+Math.random()*(3-2+1));
        //存放每次运算的结果集
        //生成3~4个参与运算的数字
        numbers.numbers = new Integer[numbers.operationNumber+1];
        for(start2=0; start2<=numbers.operationNumber; start2++) {
            numbers.numbers[start2] = (int)(0+Math.random()*(100-0+1));
        }
        //生成运算符
        numbers.operations = new Integer[numbers.operationNumber];
        for(start2=0; start2<numbers.operationNumber; start2++) {
            numbers.operations[start2] = (int)(1+Math.random()*(4-1+1));
        }
        //运算此表达式的运算结果(重点)
        //1、判断此算式是否满足条件(主要看除法是否满足)
        for(start2=0; start2<numbers.operationNumber; start2++){
            if(numbers.operations[start2] == 4) {
                if(!operation.judgeDivision(numbers.numbers[start2], numbers.numbers[start2+1])) {
                    //不满足 重新生成算式
                    judge++;
                }else {
                    continue;
                }
            }
        }
        //若满足除法后无小数,则此算式成立
        //算式中没有小数,可以生成表达式并打印
        if(judge == 0) {
            //算式中没有小数,可以生成表达式并打印
            formulas[start1] = operationString.operationSplicing(numbers.operationNumber, numbers.numbers, numbers.operations);
            System.out.println(formulas[start1]);
        }else {
            judge = 0;
            start1--;
            continue;
        }

        //调用计算函数计算结果
        CalculateMaker maker = new CalculateMaker();
        java.util.Queue<String> queue = new LinkedList<>();
        queue = maker.calculateResult(numbers.numbers, numbers.operations);
        result = maker.calculate(queue);
        formulas[start1] += String.valueOf(result);
        questionList.add(formulas[start1]);
    }
    return questionList;
    }
}

栈进行四则运算的类

public class CalculateMaker {
/**
 * 用于获得后缀表达式
 * @return
 */
public Queue<String> calculateResult(Integer[] num, Integer[] operations) {
    //用于存放之前的算式
    Queue<String> queue1 = new LinkedList<>();
    //用于存放后缀表达式
    Queue<String> queue2 = new LinkedList<>();
    int i;
    //把运算式放入队列
    for(i=0; i<num.length; i++) {
        queue1.offer(String.valueOf(num[i]));
        if(i<operations.length){
            switch (operations[i]){
                case 1:
                    queue1.add("+");
                    break;
                case 2:
                    queue1.add("-");
                    break;
                case 3:
                    queue1.add("×");
                    break;
                case 4:
                    queue1.add("÷");
                    break;
                default:
                    break;
            }
        }
    }

    //用于存放运算符
    Stack<String> stack = new Stack<>();
    //用于标注队列中运算符的位置
    i = 2;
    while(!queue1.isEmpty()) {
        //此位置是运算符
        if(i%2==1) {
            i++;
            int num1, num2;
            //把运算符放进去
            if(stack.empty()) {
                stack.push(queue1.poll());
            }else {
                //取队首元素的值(用Unicode码来判断,加减号的值小于100,乘除号的值大于100)
                num1 = Translate.translateToInt(queue1.poll());
                if(num1<100) {
                    while (!stack.isEmpty()) {
                        queue2.offer(stack.pop());
                    }
                    stack.push(Translate.translateToString(num1));
                }else {
                    num2 = Translate.translateToInt(stack.peek());
                    if(num2<100) {
                        stack.push(Translate.translateToString(num1));
                    }else {
                        queue2.offer(stack.pop());
                        if(stack.isEmpty()) {
                            stack.push(Translate.translateToString(num1));
                        }else {
                            while(!stack.isEmpty()) {
                                if(stack.isEmpty()) {
                                    stack.push(Translate.translateToString(num1));
                                    break;
                                }
                                num2 = Translate.translateToInt(stack.peek());
                                if(num2<100) {
                                    stack.push(Translate.translateToString(num1));
                                    break;
                                }else {
                                    queue2.offer(stack.pop());
                                }
                            }
                        }
                    }
                }
            }
        }else {
            i++;
            queue2.offer(queue1.poll());
            if(queue1.isEmpty()){
                while(!stack.isEmpty()) {
                    queue2.offer(stack.pop());
                }
            }
        }
    }
    //打印后缀表达式并返回
    return queue2;
}

/**
 * 根据后缀表达式计算结果
 * @param queue2
 * @return
 */
public int calculate(Queue queue2) {
    /**
     * 用于进行后缀计算
     */
    OperationImpl operation = new OperationImpl();
    //保存计算结果
    int x = 0;
    int y = 0;
    int result = 0;
    Stack<String> stack = new Stack<>();
    stack.push((String)queue2.poll());
    while(!queue2.isEmpty()) {

        String str = (String) queue2.poll();
        //遇到运算符,出栈运算,结果入栈
        if(!operation.judgeOperation(str)) {
            stack.push(str);
        }else {
                 y = Integer.valueOf(stack.pop());
                 x = Integer.valueOf(stack.pop());
                 result = operation.calculateNumber(x, y, str);
                 stack.push(String.valueOf(result));
                 //如果最终只有一个元素,则为计算的结果
                 if(stack.size() == 1 && queue2.isEmpty()) {
                    return Integer.valueOf(stack.pop());
                }
        }
    }
    return y;
}

}

主函数

public static void main(String[] args) {
    //输入想要的题目数
    System.out.println("请输入想要创建题目的数目:");
    //生成题目的数目
    Scanner scanner = new Scanner(System.in);
    int total = scanner.nextInt();
    //生成题目生成器
    FormulaMakerTest maker = new FormulaMakerTest();
    //题目集
    LinkedList<String> questionList =   maker.questionMaker(total);
    System.out.println(questionList);
    //将题目存入文件中
    FileWriting writing = new FileWriting();
    writing.WriteStringToFile(questionList);
}

控制台打印的题目

1784271-20190918101855804-1221478200.png

文件中保存的题目
1784271-20190918101905023-1447910751.png


Part3.使用github克隆项目以及提交代码

下载与安装

官网上下确实有点慢,找同学要的其他资源下的。
1784271-20190917224027550-1471181219.png

1784271-20190917224044675-1635815435.png

配置个人信息

指令:

git config --global user.name "用户名"

git config --global user.email 邮箱

克隆项目

进入这里
点这里,复制这里的url
1784271-20190917224138105-1529308205.png
1784271-20190917224824172-1271005063.png

在Git的文件夹下创建一个新的文件夹,在新的文件夹内右键选择Git Bash Here, 然后再在界面上输入git clone + 刚才复制网址,即 https://github.com/Cherish599/AchaoCalculator

1784271-20190918102241828-1879546062.png

1784271-20190917224343929-588025901.png

提交代码

成功后便会多出一个文件夹,在里面创建一个和自己github用户名一致的文件,将程序源码放进去。
1784271-20190917224402664-1818233561.png

1784271-20190917224414629-634762357.png

然后转到AchaoCalculator文件目录下(cd 文件的路径)
然后输入git add . , 再输入git commit -m "分支名称",最后输入 输入 git push,在这里会弹出框让你输入GitHub的用户名和密码即可

1784271-20190918103813984-1515816194.png

最后在GitHub上就能看到你提交的文件啦

1784271-20190918103942145-486484953.png

遇到的问题

1、第一次接触GitHub,大多是看着教程操作的,以后需要多多熟悉

2、很多指令不熟悉,有的教程上的地方我用起来会出现错误,在其他地方找了解决的办法


Part4.单元测试

因为在编程过程中有很多需要单元测试的地方,也有很多bug需要及时修改,所以没有细致的记录,在此简单的描述一下

JAVA的单元测试可以基于Junit,并需要在测试的方法前加上@Test注解且测试方法不能存在参数

1784271-20190917212623128-717075528.png

同时也可以基于main()方法来测试,并在需要的地方输出语句

1784271-20190917212635383-581693121.png

主要遇到的问题

1、表达式的生成(字符串的拼接)出现错误。因为运算符是运用1~4的随机数来保存的,所以生成算式时需要转化为加减乘除对应的符号,思考后得以解决。

2、后缀表达式生成出现错误。因为对中缀表达式转化为后缀表达式的理解还存在一些偏差。在仔细阅读概念,并不断得打印后缀表达式后,找出了代码中出现的问题,最后得以解决

3、得到后缀表达式后计算结果出现错误。后缀表达式存在一个队列中,队列中元素的出队,以及数字元素的压栈、出栈操作出现问题。在条件语句中多次进行打印操作后,找出了错误出现的位置,找到原因,最终得以解决。

4、如果除法存在小数如何解决。我才用的方法是将此次循环作废,即将循环因子的值减一,并不进行拼接操作。


Part5.回归测试

单元测试时会存在许多问题,解决了这些问题,也就是进行了回归测试,同样在编程过程中有很多的回归测试,所以没有过多去记录

这是进行单元测试后,再进行回归测试才得出的判断运算结果是否为小数的方法。

1784271-20190917212750228-1917367519.png

得出的判断方法:看两个整数相除后的结果与其强转成浮点型后的结果是否一样,一样则是整数,反之则是小数


Part6.总结

说实话感觉这次作业还是很有难度的。主要是编写代码部分就需要大量的时间与精力。数据结构在学栈的部分学习过四则运算优先级判断,但是当时没有用代码实现,所以还花时间去学习了一下。

学习Git的使用过程中,好在有很多文章可以参考,虽然陌生但是操作起来还是比较容易。

环境因为是以前就配好的,同时单元测试和回归测试其实在代码的编写中以及有所使用了,这方面进行的还是比较顺利。

总之这次作业还是让我收获颇丰,无论是对编程语言JAVA,还是数据结构中栈和队列,以及Git的使用都得到了很好的练习

转载于:https://www.cnblogs.com/nyima/p/11537353.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值