20175212童皓桢 结对编程项目-四则运算 第二周

20175212童皓桢 结对编程项目-四则运算 第二周

需求分析

  • 实现一个命令行程序,要求自动生成小学四则运算题目(加减乘除)
  • 支持多运算符
  • 测试结果的正确性,用户输入错误时给出正解
  • 实现真分数运算
  • 在不需要真分数运算时,将结果整除
  • 统计题目正确率
  • 生成题目输出到文件

  • 从文件写入

设计思路

  • 首先要能够按照按人的一般习惯,生成自左向右计算的加减乘除算式。
  • 随机生成多运算符,并随机生成相对应个数的整数
  • 利用eval方法直接计算随机生成的算式的值,并和用户的输入作比较
  • 将人计算真分数时的通分,约分方法描述成机器语言
  • 在不需要真分数运算时,将结果整除
  • 判断正确率
  • 生成题目至文件
  • 设计测试类,利用JUnit测试各情况下的的四则运算

UML类图

输入图片说明

关键代码

  • 如何生成符合要求格式的运算式
for (i = 0; i < n; i++) {
            int a = random.nextInt(5) + 1;//1-5个运算符
            int[] number = new int[a + 1];//创建一个number数组
            String ex = new String();
            for (int j = 0; j <= a; j++) {//生产a+1个数字,即2-6个数字
                number[j] = random.nextInt(100) + 1;//生成1-100的整数
            }
            for (int j = 0; j < a; j++) {
                int s = random.nextInt(4);//随机生成运算符下标
                ex += String.valueOf(number[j]) + String.valueOf(op[s]);//添加一对数字和运算符

            }
            ex += String.valueOf(number[a]);//在尾端补上一个数字
            System.out.println(ex + "=");
  • 如何验证用户输入答案的正误
int ua = reader.nextInt();//用户输入答案

            ScriptEngineManager manager = new ScriptEngineManager();
            ScriptEngine se1 = manager.getEngineByName("js");
            ScriptEngine se2 = manager.getEngineByName("js");
            String str=ex+"="+"="+ua;//将用户答案逻辑式放在字符串str中
            Boolean result =(Boolean)se1.eval(str);//用eval方法计算用户答案逻辑式
            String ca="="+se2.eval(ex);//生成correct_answer字符串存正确答案
            jud.judgeFormula(result,ca);

  • 如何进行真分数的加减乘运算
if(s==2){//计算真分数乘法运算
                int nu[]=new int[2];
                nu[0]=num[0]*num[2];
                nu[1]=num[1]*num[3];
                ca=ex+f.yuefen(nu[0],nu[1]);//将计算结果约分
            }
            else if(s==0){//计算真分数加法运算
                int nu_1[]=new int[2];
                nu_1[0]= num[0]*num[3]+num[1]*num[2];
                nu_1[1]= num[1]*num[3];
                ca=ex+f.yuefen(nu_1[0],nu_1[1]);
            }
            else {//计算真分数减法运算
                int nu_2[]=new int[2];
                nu_2[0]= num[0]*num[3]-num[1]*num[2];
                nu_2[1]= num[1]*num[3];
                if(nu_2[0]<0){//分子为负数时
                    nu_2[0]=-nu_2[0];//取反
                    ca=ex+"-"+f.yuefen(nu_2[0],nu_2[1]);//加上负号
                }
                else
                    ca=ex+f.yuefen(nu_2[0],nu_2[1]);
            }
  • 如何对分数计算结果进行约分
 public String yuefen(int m,int n){//分数约分
        FundCalculate f=new FundCalculate();
        int temp=f.gcd(m,n);
        m/=temp;
        n/=temp;
        String ca=String.valueOf(m)+"/"+String.valueOf(n);
        return ca;
    }
  • 如何在非真分数情况下构造算式整除
 public int decide(int x,int y){//判断是否整除
        Random random=new Random();
        if(x%y!=0){
            y=random.nextInt(100)+1;
            return decide(x,y);
        }
        else{
            return y;
        }
    }
 for (int j = 0; j < a; j++) {
                    switch(flag){
                        case 0:
                            s[0]= random.nextInt(4);//随机生成运算符下标
                            ex += String.valueOf(number[j]) + String.valueOf(op[s[0]]);//添加一对数字和运算符
                            if(s[0]==3){number[j+1]=f.decide(number[j],number[j+1]);}
                            break;
                        case 1:
                            s[1]= random.nextInt(4);//随机生成运算符下标
                            ex+="("+String.valueOf(number[j]) + String.valueOf(op[s[1]]);//添加左括号和数字和运算符
                            if(s[1]==3){number[j+1]=f.decide(number[j],number[j+1]);}
                            flag++;
                            break;
                        case 2:
                            s[2]=random.nextInt(4);
                            ex+=String.valueOf(number[j]) + ")"+String.valueOf(op[s[2]]);//添加右括号和数字和运算符
                            if(s[2]==3){
                                switch(s[1]){//区分之前括号里运算结果对后面数取整
                                    case 0:
                                        number[j+1]=f.decide(number[j]+number[j-1],number[j+1]);
                                        break;
                                    case 1:
                                        number[j+1]=f.decide(number[j]-number[j-1],number[j+1]);
                                        break;
                                    case 2:
                                        number[j+1]=f.decide(number[j]*number[j-1],number[j+1]);
                                        break;
                                    case 3:
                                        number[j+1]=f.decide(number[j]/number[j-1],number[j+1]);
                                        break;
                                    default:;
                                }
                            }
  • 如何在文件中输入输出
import java.io.*;

public class WAndRFile {
    String ua=new String();//用户答案
    public void writeToFile(String str){
        File fw=new File("practice.txt");//写入的文件
        try{
            Writer out=new FileWriter(fw);//指向目的地输出流
            BufferedWriter bw=new BufferedWriter(out);
            bw.write(str);//写入字符串str
            bw.newLine();//换行
            bw.close();//高级流关闭
            out.close();//关闭底层流
        }
        catch (IOException e){
            e.printStackTrace();
        }
    }
    public String readFromFile(){
        File fr=new File("practice.txt");//读取的文件
        try{
            Reader in=new FileReader(fr);//指向源的输入流
            BufferedReader br=new BufferedReader(in);
            while (br.readLine()!=null)
                ua=br.readLine();
            br.close();
            in.close();;
        }
        catch (IOException e){
            e.printStackTrace();
        }
        return ua;
    }
}

Junit测试

输入图片说明

输入图片说明

运行结果截图

  • 含真分数
    输入图片说明

  • 不含真分数

输入图片说明

  • 输出到文件

输入图片说明

代码托管地址

https://gitee.com/thz666/20175212_tong_haozhen/tree/master/src/四则运算

遇到的困难及解决办法

  • 问题一:真分数计算时,当结果为负数,输入的答案和“正确答案”时常不符,如输入-4/3,“正确答案”为4/-3.
  • 解决方法一:
if(nu_2[0]<0){//分子为负数时
                    nu_2[0]=-nu_2[0];//取反
                    ca=ex+"-"+f.yuefen(nu_2[0],nu_2[1]);//加上负号
                }

重新构造答案结构,使其符合数学标准

  • 问题二:真分数答案没有约分
  • 解决办法:
Boolean result=ua.equals(ca);
            jud.judgeFormula(result,ca);

将上述代码放在循环体中

  • 问题三:非真分数计算时会出现8位及以上小数
  • 解决办法三:事先判断是否整除,如
public int decide(int x,int y){//判断是否整除
        Random random=new Random();
        if(x%y!=0){
            y=random.nextInt(100)+1;
            return decide(x,y);
        }
        else{
            return y;
        }
    }

结对总评及评价

  • 结对学习对于编而言的确是一个很好的方法。因特殊方法的原因,我们的程序编写过程中遇到了许多各式各样的问题,大部分还是超出了知识能力范围,需要我们摸索研究。很难想象没有这样一个好的结对伙伴,这个程序的实现将会有多大的难度!
  • 最后,我希望并且有信心,通过两个人的结对将Java学习的热情和储备提升一个新的台阶。

结对照片

输入图片说明

PSP

PSPPersonal Software Process Stages预估耗时实际耗时
Planning计划30min20min
Estimate估计这个任务需要多少时间10min10min
Development开发10min10min
Analysis需求分析 (包括学习新技术)40min30min
Coding Standard代码规范 (为目前的开发制定合适的规范)5min10min
Design具体设计1h1h
Coding具体编码3h4h
· Code Review代码复审30min30min
Test· 测试(自我测试,修改代码,提交修改)1h1h
Test Report测试报告30min30min
Size Measurement计算工作量10min10min
Postmortem & Process Improvement Plan事后总结, 并提出过程改进计划30min30min
合计7h35min8h50min

参考和引用

转载于:https://www.cnblogs.com/thz666/p/10701175.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值