• JAVA结对编程--阶段总结


    一、需求分析

    1.基本需求

    • 随机生成n道题目
    • 支持整数、分数,支持多运算符
    • 能判断正误,错误时给出正确答案
    • 能计算出正确率

    2.扩展需求

    • 处理生成题目并输出到文件
    • 完成题目后从文件读入并判题
    • 支持多语言:简体中文繁体中文English
    • 生成题目去重

    二、设计思路

    在开始编程之前,我们一起仔细地阅读了项目的需求、各种具体细节,以及算法,进行了深入的讨论,总结了这次编程的主体内容,以及可能遇到的难点、问题。

    1.主体内容

    • 随机数、随机公式、随机括号(随机生成括号)的生成(用抽象类实现,重写方法getRandom)
    • 将以上随机符号拼接成随机公式
    • 中缀表达式转后缀表达式
    • 后缀表达式转结果
    • 主函数(整体拼接)

    2.难点、问题

    • 随机数、随机符号的组合方式
    • 随机括号的插入
    • 栈的知识、语法在中缀、后缀出结果的过程中的运用

    3.类图

    三、艰难的编程过程

    1.随机公式生成阶段

    • 随机数的生成
      上网查了使用公式(int)(Math.random()*x)可生成0-x的随机数

    • 随机符号的生成
      经小伙伴的提醒,可使用每个数字对应每个符号

    • 随机括号插入

      • 我刚开始想的是用小伙伴的方法,利用随机数,一个数对应在相应的位置插入括号,另一个对应不插入,成功插入括号,但发现左右括号不相等
      • 为了解决左右括号不相等的问题,我决定加入控制条件flag2,记录插入的左括号个数,在最后添加缺少的右括号,成功解决了上面的问题,但又出现了左右括号扩住一个数字的问题
      • 于是我又添加了flag4,控制不连续插入左右括号,成功解决了所有问题~!!
    • (左)括号代码:

    • 测试成功截图:

    2.中缀转后缀阶段

    • 首先的困难是栈的理解,刚开始我们看了好多资料都不太懂,直到看到这张图,我一下子就懂了,也立即给我的小伙伴也讲懂了

    • 然后就是java中有关栈的语法,上网查阅了资料
      Stack<变量名> 栈名=new Stack<变量名>()表示新建一个栈。
      栈名.pop()表示将栈顶元素弹出
      栈名.push(x)表示将x压入栈中
      栈名.push(x)表示将x压入栈中

    - 中缀转后缀就要将公式中的元素一个一个遍历,我刚开始用了charAt方法,后来出现了算数一直算不对的情况,通过debug发现charAt方法会将两位数或多位数拆成个位数,当我又一次陷入困境时,我的小伙伴又给我提供了思路,可以用```字符串名.split(" ")```,将每个字符存储起来。
    错误测试:
    ![](https://img2018.cnblogs.com/blog/1591805/201904/1591805-20190403191141359-104826463.png)
    
    - 但修正了上述错误之后,系统又开始一直报错,最后发现是字符串的判定要用```待比较的字符串.equals(要比较的字符串)```
    报错提示:
    ![](https://img2018.cnblogs.com/blog/1591805/201904/1591805-20190403191622405-2098979768.png)
    
    - 改正了上述错误之后,结果还是不对,我通过一遍一遍艰难的debug,发现了我的后缀表达式结尾竟然是数字,我又检查了一遍代码,发现是我忘记将栈中最后的元素弹出...
    debug过程:
    ![](https://img2018.cnblogs.com/blog/1591805/201904/1591805-20190403192025828-939385128.png)
    忘加的出栈过程:
    ![](https://img2018.cnblogs.com/blog/1591805/201904/1591805-20190403192358269-306430264.png)
    
    ### 3.后缀转结果阶段
    - 在这里我又想到了小伙伴给我提供的思路,可以用```split```语句将后缀表达式依次遍历,利用栈,遇到符号就将栈顶的连个元素弹出栈,并进行计算。
    - 进行测试时遇到了字符串忘记转整型的问题,小伙伴上网查询了字符串转整型的方法```Integer.valueOf(字符串)```,测试成功!!
    
    ### 4.最终拼接阶段
    - 这一部分比较简单,就出现了正确率计算错误的问题,最后发现正确率应该这样子加double括号
    ![](https://img2018.cnblogs.com/blog/1591805/201904/1591805-20190403194448262-403305150.png)
    
    ### 5.最后的最后
    - 测试成功~~~~~~~~
    ![](https://img2018.cnblogs.com/blog/1591805/201904/1591805-20190403194641005-1382323768.png)
    
    ### 6.后续发现的bug
    - 除法计算时会向下取整,而且会出现分母为0的情况,而且程序还有待优化、不够简洁,下周会进行修复
    
    ## 四、核心代码解释
    - 生成随机数代码:
    

    import java.util.;
    import java.lang.
    ;
    public class getRandom {
    String s;
    String str[]=new String[100];
    char a,b; //a:插入的数字,b:插入的符号
    int x; //x:插入符号的个数
    char flag1,flag3; //flag1:左括号,flag3:右括号
    int flag2=0,flag4=0; //flag2:插入左括号的个数,flag4:控制不连续插入左右括号
    public void storeRandom(int n) {
    for(int i=1;i<=n;i++) { //存储随机生成的的每个公式
    s="";
    x=(int)(Math.random()*6)+3;
    Random r3=new RandomZuo();
    flag1=r3.getRandom();
    for(int j=1;j<=x;j++) { //依次插入数字、公式
    Random r1=new RandomNum();
    a=r1.getRandom();
    s=s+(int)a+" ";
    if(flag2>0&&flag40) {
    Random r6=new RandomYou();
    flag3=r6.getRandom();
    if(flag3
    ')') {
    s=s+flag3+" ";
    flag2--;
    }
    }
    flag4=0;
    Random r2=new RandomChar();
    b=r2.getRandom();
    s=s+b+" ";
    Random r4=new RandomZuo();
    flag1=r4.getRandom();
    if(flag1=='('&&j<x-1) {
    s=s+flag1+" ";
    flag2++;
    flag4=1;
    }
    }
    Random r5=new RandomNum();
    s=s+(int)r5.getRandom()+" ";
    while(flag2!=0) {
    s=s+")"+" ";
    flag2--;
    }
    str[i]=s;
    }
    }
    public String[] retRandom() {
    return str;
    } //返回随机生成的公式
    }

    
    - 中缀转后缀代码:
    

    import java.util.;
    public class ZhongzhuiToHouzhui {
    public String result(String s) {
    Stack sta = new Stack(); //新建栈
    String str = "";
    String[] s1=s.split(" ");
    int length = s1.length;
    for (int i = 1; i <= length; i++) { //依次遍历元素,转为后缀表达式
    String temp;
    String c = s1[i-1];
    if (c.equals(" "))
    break;
    else if (c.equals("+") || c.equals("-")) { //遇到优先级最低的“+”、“-”,弹出“(”之前的所有元素
    while (sta.size() != 0) {
    temp = sta.pop();
    if (temp.equals("(")) {
    sta.push("(");
    break;
    }
    str = str + temp + " ";
    }
    sta.push(c);
    } else if (c.equals("
    ")|| c.equals("/")) { //遇到优先级高的“”、“/”,弹出“(”之前的“”、“/”
    while (sta.size() != 0) {
    temp = sta.pop();
    if (temp.equals("(") || temp.equals("+") || temp.equals("-")) {
    sta.push(temp);
    break;
    } else
    str = str + temp + " ";
    }
    sta.push(c);
    } else if (c.equals("(")) { //遇到“(”直接入栈
    sta.push(c);
    } else if (c.equals(")")) { //遇到“)”,弹出“(”之前的所有元素
    while (sta.size() != 0) {
    temp = sta.pop();
    if (temp.equals("("))
    break;
    else
    str = str + temp + " "; //遇到数字,直接存入数组
    }
    } else
    str = str + c + " ";
    }
    while (sta.size()!=0){ //弹出栈中剩余的元素
    str=str+sta.pop()+" ";
    }
    return str;
    }
    }

    
    - 后缀转结果代码
    

    import java.util.;
    import java.lang.
    ;
    public class getResult {
    public int getResult(String s){
    Stack stack=new Stack(); //新建栈(Integer类型)
    String[] str=s.split(" ");
    int n=str.length;
    int a=0,b=0;
    for (int i=1;i<=n;i++){ //依次遍历元素,计算结果
    String c=str[i-1];
    if (c.equals("+") || c.equals("-") || c.equals("") || c.equals("/")){ //遇到符号,弹出栈顶两个元素,并计算结果
    a=stack.pop();
    b=stack.pop();
    stack.push(jisuan(b,a,c)); //将计算后的结果重新压入栈中
    }
    else { //遇到数字,直接入栈
    stack.push(Integer.valueOf(c));
    }
    }
    return stack.pop();
    }
    public int jisuan(int a,int b,String c){ //计算结果
    if (c.equals("+")){
    return a+b;
    }
    else if (c.equals("-")){
    return a-b;
    }
    else if (c.equals("
    ")){
    return a*b;
    }
    else if (c.equals("/")){
    if (b==0){
    System.out.println("生成的公式出现分母为0的情况,错误!");
    System.exit(1);
    return 1;
    }
    else
    return a/b;
    }
    else{
    System.out.println("Error!");
    return 0;
    }
    }
    }

    
    ## 五、运行结果截图
    ![](https://img2018.cnblogs.com/blog/1591805/201904/1591805-20190403200758352-589339656.png)
    ![](https://img2018.cnblogs.com/blog/1591805/201904/1591805-20190403200809345-135732605.png)
    
    ## 六、代码托管地址
    - [结对代码](https://gitee.com/lx25t/pairing_project/tree/master/%E7%BB%93%E5%AF%B9%E4%BB%A3%E7%A0%81)
    
    ## 七、对结对的小伙伴进行评价
    - 我在本次结对任务中扮演**领航员**的角色,在对方遇到问题时给提供解决思路。我的小伙伴在本次结对中扮演**领航员**的角色,负责编写代码。
    
    ## 八、总结
    - 这次的结对编程是对我们的挑战,也是对我分析、解决问题已经编程能力的挑战。合作完成任务提高了彼此的积极性,也为我们的学习提供了一个新的方式。在不断完善代码的过程中,也增强了自身对程序的进一步理解。有所收获但也有许多不足之处。分工、配合、效率……仍然是我们接下来的学习中的一大挑战,我们会在接下来的任务中逐渐磨合,将问题逐一攻破。
    ## 九、预估与实际
    
    |Planning|计划|预估耗时(分钟)|实际耗时|
    |:------|:------|:------|:------|
    |Estimate|预估这个任务需要多长时间|1110|1580|
    |**Development**|**开发**|  |  |
    |Analysis|需求分析(包括学习新技术)|40|90|
    |Design Spec|生成设计文档|30|30|
    |Design Review|设计复审|60|60|
    |Coding Standard|代码规范(为目前的开发制定合适的规范)|40|40|
    |Design|具体设计|70|70|
    |Coding|具体编码|700|1100|
    |Code Review|代码复审|60|60|
    |Test|测试(自我测试、修改代码、提交修改)|40|60|
    |**Reporting**|**报告**|  |  |
    |Test Report|测试报告|20|20|
    |Size Measurement|计算工作量|10|10|
    |Postmortem&Process Improvement Plan|事后总结并提出改进计划|40|40|
    |  |合计|1110|1580|
    
    ## 十、参考
    - https://en.wikipedia.org/wiki/Shunting-yard_algorithm
    - http://hczhcz.github.io/2014/02/27/shunting-yard-algorithm.html
    - https://www.cnblogs.com/dushik/p/8580705.html
  • 相关阅读:
    Qt简介以及如何配置Qt使用VS2010进行开发
    QT里重定向另外一个控制台程序的输出
    windows下制作PHP扩展
    20款Notepad++插件下载和介绍
    音频编码协议介绍
    用 PHP 读取文件的正确方法
    QT进程间通信
    关于YUV色彩空间
    解析xml 四种
    System.getProperty
  • 原文地址:https://www.cnblogs.com/ln-0407/p/10652954.html
Copyright © 2020-2023  润新知