编程语言
首页 > 编程语言> > 20175209王梓鸿 结对编程项目—四则运算 第一周 阶段总结

20175209王梓鸿 结对编程项目—四则运算 第一周 阶段总结

作者:互联网

20175209王梓鸿 结对编程项目—四则运算 第一周 阶段总结

一、需求分析

1.题目要求:

二、设计思路

1.编写背景及完成情况

2.开始编写之前的想法

在大一下C语言课上老师也让我们写过四则运算的程序,最初我想在之前的基础上进行修改,但对比要求后发现差别很大,因此推翻了这个想法。在开始写之前,我仔细阅读了题目及相关要求,大概划分了需要完成的部分。主要分为产生问题,计算,和比较判断三个部分,但其实计算部分是最复杂的,其中包含的中缀转后缀采用的逆波兰法并不是很理解,也花费了相当长的时间去理解,因为时间紧张,晚上熄灯后也在思考应该怎样去完成好一部分,这也是编写程序时最令我头疼的地方,因为即使弄懂了原理,在具体执行到代码时还会存在能否成功运行的问题。

3.我们的设计和分工

结对项目,当然要两个人一起完成,为了缩短我们的工作时间,我们进行了简单的分工

4.UML图

三、实现过程中关键代码的解释

public class GetAnswer {    
    double result, num = 0;    
    int result1;    
    String q;    
    Stack stack;    
    public GetAnswer() {        
        stack = new Stack();    
    }    
    void set(String question) {   //输入后续排列的字符串        
        q = question;   
    }    
    int get() {        
        double op1, op2;        
        StringTokenizer token = new StringTokenizer(q, " ");        
        String temp;        
        while (token.hasMoreTokens()) {           
            temp = token.nextToken();            
            if (Isop(temp) == 1)//遇到操作符,弹出栈顶的两个数进行运算            {                
                op2 = (double) stack.pop();                
                op1 = (double) stack.pop();//弹出最上面两个操作数                
                result = cal(temp.charAt(0), op1, op2);//根据运算符进行运算                
                stack.push(result);//将计算结果压栈            
            } 
           else {                
                num = Double.valueOf(temp);                
                stack.push(num);//操作数入栈            
            }        
        }        
        if (result >= 0)           
            result1 = (int) Math.floor(result);       //将结果舍去小数,无论正负        
        else                
            result1 = (int) Math.ceil(result);        
        return result1;//输出结果    
    }    
    double cal(char op, double a, double b) {           //对栈顶弹出的两个数进行运算        
        double c = 0;        
            switch (op) {            
                case '+':                
                    c = a + b;                
                    break;            
                case '-':                
                    c = a - b;                
                    break;            
                case '*':                
                    c = a * b;               
                    break;            
                case '÷':                
                    if (b == 0) {                    
                        System.out.println("出现了分母为0的情况,请重新开始");                    
                        System.exit(0);                
                    }                
                    else {                    
                        c = a / b;                    
                        break;                
                    }       
            }        
            return c;    
    }    
    int Isop(String op) {       //判断是不是运算符        
        if (op.equals("+") || op.equals("-") || op.equals("*") || op.equals("÷") || op.equals("/"))            
            return 1;        
        else return 0;    
    }
}

简要说明:我们考虑到了计算机在进行计算时存在的问题,当遇到除法的时候,如果数据类型为整型,那么计算机会将结果自动向下取整,当出现了多个除法接连出现时,会将每一次的结果都向下取整后再进行下一个除法运算,这样就会与实际算出来的结果有较大的误差。因此我们选择将数据类型定义为浮点型,将算出的最终结果向下取整再转换为整型,这样在实际运算时就不会因为计算机计算的方式而产生误差

public class MidToEnd {    
    String C = new String();    
    String End = "";            //存储数字的字符串    
    public void ChangeString(String str) {        
        C = str;    
    }   
    public String ChangeOrder() {        
        Stack store = new Stack();     //创建一个存储字符的栈        
        for (int i = 0; i < C.length(); i++) {            
            char op = C.charAt(i);     //将索引值为i处的字符的值返回            
            if (op >= '0' && op <= '9')                
                End = End + op;            
            else if (op == '(')                
                store.push(op);            
            else if (op == '+' || op == '-' || op == '*' || op == '÷') {                
                End = End + " ";                
                if (store.empty())                    
                    store.push(op);                
                else if (compareValue(op) > compareValue((char) store.peek()))    //比较运算符优先级                    
                    store.push(op);               
                else {                    
                    End = End + String.valueOf(store.pop()) + " ";                    
                    i--;                
                }            
            } 
            else if (op == ')') {                
                while ((char) store.peek() != '(') {                    
                    End = End + " " + String.valueOf(store.pop());                
                }                
                store.pop();            
            }        
        }        
        while (!store.empty())            
            End = End + " " + String.valueOf(store.pop());        
        return End;    
    }    
    public int compareValue(char chi) {        
    nt number = 0;        
    switch (chi) {            
        case '(':                
            number = 1;                
            break;            
        case '+':            
        case '-':               
            number = 2;               
            break;            
        case '*':            
        case '÷':                
            number = 3;                
            break;            
        case ')':                
            number = 4;               
            break;            
        default:               
            number = 0;                
            break;       
        }        
        return number;   
    }
}

简要说明:因为在压栈和弹栈的过程中涉及到运算符的优先级问题,因此需要对运算符的优先级进行比较,否则在转换为后缀计算的时候会与正常的结果不同

public class GetQuestion {    
    public String get(int a,int b) {        
        String q = "";        
        int flag1 = 0, flag2 = 0, flag3 = 1, flag4 = 0, flag5 = 0, countTotal;  // flag1记录插了几个左括号,flag2标记下一个插入的是数字还是运算符,countTotal记录共插入几个字符        
        GetNumber num = new GetNumber();                                       //flag3限制括号数量,flag4控制左右括号之间至少间隔一个运算符        
        GetOperator op = new GetOperator();                                     //flag5控制左括号不连续出现        
        GetBracket bra = new GetBracket();        
        for (countTotal = 0; flag3 == 1 && countTotal < b; ) {            
            GetNumber random = new GetNumber();            
            int rand = (random.GetNumber(a)) % 2;            
            if (flag1 == 3)                
                flag3 = 0;            
            if (countTotal != 0 && rand == 1 && flag2 % 2 == 0 && flag3 == 1 && flag4 % 2 == 0 && flag5 % 2 == 0 && countTotal < b-3) {                    //插左括号                
                q += bra.setBracket(0);                
                flag1++;                
                flag5 = 1;                
                countTotal++;            
            } 
            else if (rand == 0 && flag2 % 2 == 0 || flag5 % 3 == 0 && flag2 % 2 == 0){                                         
//插数字                
                q += num.GetNumber(a);                
                flag2++;                
                flag5 = 0;                
                countTotal++;           
            }
            else if (rand == 1 && flag1 > 0 && flag2 % 2 == 1 && flag4 % 2 == 1) {         //插右括号                
                q += bra.setBracket(1);                
                flag1--;                
                countTotal++;            
            } 
            else if (rand == 0 && flag2 % 2 == 1) {                                          //插运算符                
                q += op.GetOperator();                
                flag2++;                
                flag4++;                
                countTotal++;            
            }        
        }        
        while (q.endsWith("+") || q.endsWith("-") || q.endsWith("*") || q.endsWith("÷") || q.endsWith("(")) {            
            int L = q.length();            
            if (q.endsWith("("))                
                flag1--;            
            q = q.substring(0, L - 1);       
        }        
        while (flag1 > 0) {            
            q += bra.setBracket(1);            
            flag1--;        
        }        
        return q;    
    }
}

四、运行过程截图

五、代码托管地址

https://gitee.com/wangzihong/20175209/tree/master/src/CalculateSystem

六、过程中遇到的问题

七、对结对伙伴的评价

我觉得我的小伙伴非常的聪明,反应也很迅速,我们二人的工作量基本相同,但是他往往比我更快完成,我偶尔有困惑的问题在经过讨论之后他总是能给出我一些很好的建议去解决问题,当然在编写的过程中也有意见不一样的地方,有的时候会进行很激烈的讨论。两个人之间的磨合还稍微有些欠缺,在以后的作业完成中还需要相互磨合

八、总结

本次结对作业可以说是大学学习中最为庞大的一项内容了,在讨论和编写的时候花费了大量的时间,并且总是遇到很多问题,需要花费大量的时间查找资料,调试的过程也非常心酸,但是能将这次的作业顺利完成也让我感觉非常有成就,同时让我对这门课的学习更加有兴趣,也明白了结对学习的重要性。当然我们的代码还存在欠缺,这周的有一些要求还没有实现,下周的目标是现将这周欠缺的任务补齐,然后再尝试一下把扩展需求完成,希望能让代码的功能更加全面

九、预估时间与实际时间

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划
·Estimate · 估计这个任务需要多少时间 790 1320
Development 开发
· Analysis · 需求分析 (包括学习新技术) 50 120
· Design Spec · 生成设计文档 30 30
· Design Review · 设计复审 (和同事审核设计文档) 40 60
· Coding Standard · 代码规范 (为目前的开发制定合适的规范) 20 50
· Design · 具体设计 40 70
· Coding · 具体编码 500 750
· Code Review · 代码复审 20 60
· Test · 测试(自我测试,修改代码,提交修改) 30 120
Reporting 报告
· Test Report · 测试报告 30 20
· Size Measurement · 计算工作量 10 10
· Postmortem & Process Improvement Plan · 事后总结, 并提出过程改进计划 20 30
合计 790 1320

标签:结对,20175209,countTotal,int,王梓鸿,运算符,String,&&,op
来源: https://www.cnblogs.com/wangzihong0213/p/10657089.html