首页 > 其他 > 详细

20175217 结对编程项目-四则运算 第一周阶段性总结

时间:2019-04-03 22:07:14      阅读:127      评论:0      收藏:0      [点我收藏+]

一、需求分析

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压入栈中
  • 中缀转后缀就要将公式中的元素一个一个遍历,我刚开始用了charAt方法,后来出现了算数一直算不对的情况,通过debug发现charAt方法会将两位数或多位数拆成个位数,当我又一次陷入困境时,我的小伙伴又给我提供了思路,可以用字符串名.split(" "),将每个字符存储起来。
    错误测试:
    技术分享图片

  • 但修正了上述错误之后,系统又开始一直报错,最后发现是字符串的判定要用待比较的字符串.equals(要比较的字符串)
    报错提示:
    技术分享图片

  • 改正了上述错误之后,结果还是不对,我通过一遍一遍艰难的debug,发现了我的后缀表达式结尾竟然是数字,我又检查了一遍代码,发现是我忘记将栈中最后的元素弹出...
    debug过程:
    技术分享图片
    忘加的出栈过程:
    技术分享图片

3.后缀转结果阶段

  • 在这里我又想到了小伙伴给我提供的思路,可以用split语句将后缀表达式依次遍历,利用栈,遇到符号就将栈顶的连个元素弹出栈,并进行计算。
  • 进行测试时遇到了字符串忘记转整型的问题,小伙伴上网查询了字符串转整型的方法Integer.valueOf(字符串),测试成功!!

4.最终拼接阶段

  • 这一部分比较简单,就出现了正确率计算错误的问题,最后发现正确率应该这样子加double括号
    技术分享图片

5.最后的最后

  • 测试成功~~~~~~~~
    技术分享图片

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&&flag4==0) {
                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<String> sta = new Stack<String>();   //新建栈
        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<Integer> stack=new Stack<Integer>();   //新建栈(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;
    }
}
}

五、运行结果截图

技术分享图片
技术分享图片

六、代码托管地址

七、对结对的小伙伴进行评价

  • 我在本次结对中扮演领航员的角色,负责编写代码。小伙伴扮演领航员的角色,在我遇到问题时给我提供解决思路~

八、总结

  • 这次的结对编程是对我们的挑战,也是对我的编程能力的挑战,之前从来没有写过这么大的题目,刚开始的思路全是乱的,心态动不动就会崩溃,晚上做梦都在想代码,还好有小伙伴一直给我提供思路,才一直坚持了下来。当然,收获也是满满的,感觉我的编程能力也得到了很大的提高。

九、预估与实际

明天小伙伴会把表格做出来

十、参考

20175217 结对编程项目-四则运算 第一周阶段性总结

原文:https://www.cnblogs.com/wyf20175217/p/10651653.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!