高级软件工程第二次作业

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了高级软件工程第二次作业相关的知识,希望对你有一定的参考价值。

1 项目 GitHub 地址

 GitHub地址:https://github.com/huzhiquan/sizeyunsuan

2 PSP

PSP

Personal Software Process Stages

预估耗时(分钟)

实际耗时(分钟)

Planing

计划

10

10

Estimate

估计这个任务需要多少时间

10

10

Development

开发

700

900

Analysis

需求分析(包括学习新技术)

40

70

Design Spec

生成设计文档

30

30

Design Review

设计复审 (和同事审核设计文档)

10

10

Coding Standard

代码规范 (为目前的开发制定合适的规范)

20

10

Design 

具体设计

30

50

Coding

具体编码

500

600

Coding Review

代码复审

60

90

Test

测试(自我测试,修改代码,提交修改)

60

90

Reporting

报告

120

180

Test Report

测试报告

60

150

Size Measurement

计算工作量

10

10

Postmortem & Process Improvement Plan

事后总结, 并提出过程改进计划

30

30

合计

 

850

1490

3 项目要求

1、 参与运算的操作数(operands)除了100以内的整数以外,还要支持真分数的四则运算。操作数必须随机生成。

2、 运算符(operators)为 +, ?, ×, ÷ 运算符的种类和顺序必须随机生成。

3、 要求能处理用户的输入,并判断对错,打分统计正确率。

4、 使用 -n 参数控制生成题目的个数。

附加要求

1、 支持带括号的多元复合运算

2、 运算符个数随机生成(考虑小学生运算复杂度,范围在2~10)

4 解题思路

   先不考虑附加要求的话,本题可以简化为100以内的整数和真分数的四则运算,运算符个数定为3个,真分数,整数,操作符均随机生成。等完成基本要求,再考虑附加要求比较好。

对于本题,首先要考虑的是以什么结构去存储真分数,运算简单,不容易出错。本项目的思想是将真分数用String保存,在运算时,将string形式的分数中的分子分母以/为界,保存到二维数组中,分开运算。运算的时候,要注意分子分母为0等的特殊情况。

然后要考虑的是在随机生成的整个表达式中,乘法和除法要优先计算,这里暂不考虑带括号的表达式。因此将表达式转换为后缀表达式再计算结果,这之中用到了栈,容易出现栈溢出的问题,需要考虑。

最后将结果用字符串表示,并与用户输入的进行比较,判断对错。

5 代码说明

1、 随机生成真分数,操作符和整数

//生成真分数

    public static int[] generateFraction()

    {

        int [] fraction=new int[2];

        int temp=0;

        int x,y;

        x=new Random().nextInt(99)+1;

        y=new Random().nextInt(99)+1;

        while(x==y)

        {

            y=new Random().nextInt(99)+1;

        };

        if(x>y)

        {

            temp=x;

            x=y;

            y=temp;

        }

        fraction[0]=x;

        fraction[1]=y;

        return fraction;

    }

//生成操作符

    public static String generateOperater()

    {

        String[] Operater={"+","-","×","÷"};

        int x=new Random().nextInt(4);

        String Op=Operater[x];

        return Op;

    }

//生成数

//生成整数或随机数本身也是随机的

    public static String generateNum()

    {

        int x=new Random().nextInt(2);

        if(x==0)

        {

            int y=new Random().nextInt(100);

            return String.valueOf(y);

        }

        else {

            int []y=generateFraction();

            return String.valueOf(y[0])+"/"+String.valueOf(y[1]);

        }

    }

1、 加法计算

//计算加法

    public static String add(String a,String b){

       

        if((a.contains("/")==false)&&(b.contains("/")==false)){

            int intofa=Integer.valueOf(a);

            int intofb=Integer.valueOf(b);

            return String.valueOf(intofa+intofb);

        }

        else if((a.contains("/")==true)&&(b.contains("/")==false))

        {

            int []result = new int[2];

            int []fractionofa=strToarr(a);

            int intofb=Integer.valueOf(b);

            //分母化同并实现运算

            result[0]=fractionofa[0]+fractionofa[1]*intofb;

            result[1]=fractionofa[1];

            return simplify(result);           

        }

        else if((a.contains("/")==false)&&(b.contains("/")==true))

        {

            int []result = new int[2];

            int intofa=Integer.valueOf(a);

            int []fractionofb=strToarr(b);

            //分母化同并实现运算

            result[0]=intofa*fractionofb[1]+fractionofb[0];

            result[1]=fractionofb[1];

            return simplify(result);

        }

        else{

            int []result =new int[2];

            int []fractionofa=strToarr(a);

            int []fractionofb=strToarr(b);

            //分母化同并实现运算

            result[0]=fractionofa[0]*fractionofb[1]+fractionofa[1]*fractionofb[0];

            result[1]=fractionofa[1]*fractionofb[1];

            return simplify(result);

        }

    }  

2、 中缀表达式转换为后缀表达式

//由中缀转换为后缀

    private String infixTopost()

    {

        String[] strArr=getInfix(input).split(" ");

        for (int i = 0; i < strArr.length; i++) {

            String x=strArr[i];

            switch(x){

            //当x为符号时,与当前栈顶的符号比优先级,若x的优先级≤栈顶元素,则将栈顶元素出栈,再将x入栈

            case "+":

            case "-":transfer(x,1);break;

            case "×":

            case "÷":transfer(x,2);break;

            //当x为数字时,直接加到post中

            default:post+=" "+x;break;

            }

        }

        while (stack.isEmpty()==false) {//将栈中最后一个元素出栈

            post += " " + stack.pop();

        }

        post=post.trim();//去掉第一个空格

        //System.out.println("后缀表达式:"+post);

        return post;

    }

    //当x为符号时,与当前栈顶的符号比优先级,若x的优先级≤栈顶元素,则将栈顶元素出栈,再将x入栈

    private void transfer(String x,int priority)

    {

        while(stack.isEmpty()==false){

            String top=stack.pop();

            int priorityoftop=getpriority(top);

            if(priority>=priorityoftop)//当x的优先级>=栈顶元素优先级时

            {

                stack.push(top);

                break;

            }

            else{//当x的优先级<栈顶元素优先级时

                post+=" "+top;         

            }

        }

        stack.push(x);

    }

    //判断操作符的优先级

    private int getpriority(String top) {

        // TODO Auto-generated method stub

        if(top.equals("+")==true||top.equals("-")==true)

        {

            return 1;

        }

        else return 2;

    }

4、计算后缀表达式

private String infixTopost()

    {

        String[] strArr=getInfix(input).split(" ");

        for (int i = 0; i < strArr.length; i++) {

            String x=strArr[i];

            switch(x){

            //当x为符号时,与当前栈顶的符号比优先级,若x的优先级≤栈顶元素,则将栈顶元素出栈,再将x入栈

            case "+":

            case "-":transfer(x,1);break;

            case "×":

            case "÷":transfer(x,2);break;

            //当x为数字时,直接加到post中

            default:post+=" "+x;break;

            }

        }

        while (stack.isEmpty()==false) {//将栈中最后一个元素出栈

            post += " " + stack.pop();

        }

        post=post.trim();//去掉第一个空格

        //System.out.println("后缀表达式:"+post);

        return post;

    }

5、计算算式结果

//由后缀表达式得结果

    public String postToresult()

    {

        String[] strArr=infixTopost().split(" ");

        for(int i = 0; i < strArr.length; i++){

            String temp = strArr[i];

            if(isOperater(temp)==false){//是数字时,入栈

                stack.push(temp);

            }else{//是操作符时,将栈顶两个元素进行运算,结果入栈

                stack.push(compute1(temp));

            }

        }

        return stack.pop();

    }

    //四则运算

    private static String STACK_ERROR="THE STACK IS NULL!";

    private String compute1(String temp) {

        // TODO Auto-generated method stub

        compute com=new compute();

        String result = "";

        String a;

        String b;

        while(true){

            if(stack==null||stack.size()==0){return "栈为空a1";}

            String tempa=stack.pop();

            if(tempa.equals(STACK_ERROR)){return "栈为空a2";}

            if(!tempa.equals("")){a=tempa;break;}

        }

        while(true){

            if(stack==null||stack.size()==0){return "栈为空b1";}

            String tempb=stack.pop();

            if(tempb.equals(STACK_ERROR)){return "栈为空b2";}

            if(!tempb.equals("")){b=tempb;break;}

        }

        switch(temp)

        {

            case "+":

                result=com.calculate(b, a, "+");

                //System.out.println("test:"+b+"+"+a+"="+ result);

                break;

            case "-":

                result=com.calculate(b, a, "-");

                //System.out.println("test:"+b+"-"+a+"="+ result);

                break;

            case "×":

                result=com.calculate(b, a, "×");

                //System.out.println("test:"+b+"×"+a+"="+ result);

                break;

            case "÷":

                if(a.equals("0")){return "被除数为0";};

                result=com.calculate(b, a, "÷");

                //System.out.println("test:"+b+"÷"+a+"="+ result);

                break;

            default:break;

        }

        return result;     

    }

6 测试运行

 技术分享

7个人小结

 本次项目对于我来说是个不小的挑战,且项目本身还存在很多瑕疵:不支持带括号的多元复合运算,运算符的个数不能随机生成,且在生成很多算式的时候,运行会变慢等等。还有很多需要优化的地方,由此经历我也更明白自己的薄弱点在哪里,在未来的学习中,我会继续提升自己,克服短板。

以上是关于高级软件工程第二次作业的主要内容,如果未能解决你的问题,请参考以下文章

高级软件工程-第二次作业-数独

软件工程-第二次作业

软件工程第二次作业

软件第二次作业

高级软件工程2017第2次作业

软件工程——第二次作业