zoukankan      html  css  js  c++  java
  • 个人作业1——四则运算题目生成程序(基于控制台)

    码云地址:https://git.oschina.net/lzx84/szys

    题目:

    从《构建之法》第一章的 “程序” 例子出发,像阿超那样,花二十分钟写一个能自动生成小学四则运算题目的命令行 “软件”。

    满足以下需求:

      1. 除了整数以外,还要支持真分数的四则运算,真分数的运算,例如:1/6 + 1/8 = 7/24
      2. 运算符为 +, −, ×, ÷
      3. 并且要求能处理用户的输入,并判断对错,打分统计正确率。
      4. 要求能处理用户输入的真分数, 如 1/2, 5/12 等
      5. 使用 -n 参数控制生成题目的个数,例如执行下面命令将生成10个题目
        Myapp.exe -n 10

    需求分析:

    • 需要处理分数,包括化简分数、识别整数等。并考虑特殊情况,如分数分母不为0等。考虑到题目要求小学水平,则分子分母数值不超过100。
    • 需要编写分数四则运算的算法,并考虑特殊情况,如减法结果不能为负数,除法中除数不能为0等。
    • 需统计用户正确的题目数,与总题目数。
    • 需要实现字符串的识别与比较。

    功能实现:

    • 基本功能:能随机生成若干四则运算式,并检测用户答案,统计正确率。
    • 扩展功能:实现多项运算、统计做题时长、避免重复题型、控制题目难度等(未实现)
    • 高级功能:实现错题统计功能、实现多用户竞赛功能、实现更复杂的运算等(未实现)

    设计实现:

        Fraction类:

        Calculate类:

        Dofrac类:

    代码说明:

      Fraction类:

    public class Fraction {
    
        private int fenzi;
        private int fenmu;
    
        public Fraction() {
            super();
        }
    
        public Fraction(int fenzi, int fenmu) {
            super();
            this.fenzi = fenzi;
            this.fenmu = fenmu;
            this.simplify(fenzi, fenmu); //在构造函数中直接化简分数(感觉此方法欠妥)
        }
    
    
    
        public void simplify(int fenzi, int fenmu) { 
            int GCD = Dofrac.GCD(fenzi, fenmu);
            this.fenzi = fenzi / GCD;
            this.fenmu = fenmu / GCD;
        }//化简分数
    
        @Override
        public String toString() {
            if (fenzi == 0) {
                return 0 + "";
            } else if (fenzi % fenmu == 0) {
                return fenzi / fenmu + "";
            } else
                return fenzi + "/" + fenmu;
        }//改写toString,输出为分数形式
    
        public int getFenzi() {
            return fenzi;
        }
    
        public void setFenzi(int fenzi) {
            this.fenzi = fenzi;
        }
    
        public int getFenmu() {
            return fenmu;
        }
    
        public void setFenmu(int fenmu) {
            this.fenmu = fenmu;
        }
    
        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + fenmu;
            result = prime * result + fenzi;
            return result;
        }
    
        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            Fraction other = (Fraction) obj;
            if (fenmu != other.fenmu)
                return false;
            if (fenzi != other.fenzi)
                return false;
            return true;
        }
    
    }

    Calculate类:

    public class Calculate {
        public static Fraction add(Fraction f1, Fraction f2) {
    
            int fz1 = f1.getFenzi();
            int fz2 = f2.getFenzi();
            int fm1 = f1.getFenmu();
            int fm2 = f2.getFenmu();
            Fraction f = new Fraction(fz1 * fm2 + fm1 * fz2, fm1 * fm2);
            return f;
    
        }//加法运算
    
        public static Fraction sub(Fraction f1, Fraction f2) {
            int fz1 = f1.getFenzi();
            int fz2 = f2.getFenzi();
            int fm1 = f1.getFenmu();
            int fm2 = f2.getFenmu();
            Fraction f = new Fraction(fz1 * fm2 - fm1 * fz2, fm1 * fm2);
            return f;
        }//减法运算
    
        public static Fraction mul(Fraction f1, Fraction f2) {
            int fz1 = f1.getFenzi();
            int fz2 = f2.getFenzi();
            int fm1 = f1.getFenmu();
            int fm2 = f2.getFenmu();
            Fraction f = new Fraction(fz1 * fz2, fm1 * fm2);
            return f;
        }//乘法运算
    
        public static Fraction div(Fraction f1, Fraction f2) {
            int fz1 = f1.getFenzi();
            int fz2 = f2.getFenzi();
            int fm1 = f1.getFenmu();
            int fm2 = f2.getFenmu();
            Fraction f = new Fraction(fz1 * fm2, fm1 * fz2);
            return f;
        }//除法运算
    
        public static boolean compare(Fraction f1, Fraction f2) {
            int fz1 = f1.getFenzi();
            int fz2 = f2.getFenzi();
            int fm1 = f1.getFenmu();
            int fm2 = f2.getFenmu();
            if (fz1 * fm2 >= fz2 * fm1) {
                return true;
            } else{

    return false;

    }

    }//比较两分数的大小 }

    Dofrac类:

    public class Dofrac {
    
        public static Fraction CreatFrac() {
            int fz, fm,co;
    co=(int)(Math.random()*2);//co取[0,1]得随机值,分别代表分数和整数

              if(co==0){

                  fm = (int) (2 + Math.random() * (100 - 2 + 1));//分母为2-100的随机数
                  fz =(int) (0 + Math.random() * (fm - 0 + 1));//分子为 0--fm 的随机数(确保真分数)
              }else {
                  fm=1;
                  fz=(int) (0 + Math.random() * (100 - 0 + 1));
              }

    
            Fraction frac = new Fraction(fz, fm);
            return frac;
        }//创建随机分数
    
        public static boolean check(String input) {
            if (input.matches("[0-9]+")||input.matches("[0-9]+/[0-9]+")) {
                return true;
            } else
                {
                return false;
            }
        }//利用正则表达式处理用户输入的答案
    public static int GCD(int m, int n) { while (true) { if ((m = m % n) == 0) return n; if ((n = n % m) == 0) return m; } }//计算最大公约数
    public static Fraction MakeFor(Fraction f1, Fraction f2, int op, int i) { Fraction result = new Fraction(); switch (op) { case 1: { result = Calculate.add(f1, f2); System.out.println("第" + i + "题:" + f1.toString() + "+" + f2.toString()); break; } case 2: { if (!Calculate.compare(f1, f2)) { Fraction temp = f1; f1 = f2; f2 = temp; }//比较两分数的大小,若减数小于被减数,则将两个数交换 result = Calculate.sub(f1, f2); System.out.println("第" + i + "题:" + f1.toString() + "-" + f2.toString()); break; } case 3: { result = Calculate.mul(f1, f2); System.out.println("第" + i + "题:" + f1.toString() + "*" + f2.toString()); break; } case 4: { if (f2.getFenzi() == 0) { f2.setFenzi((int) (1 + Math.random() * (10 - 1 + 1))); }//若除数分子为0,则分子重新取一个1——100的随机数 result = Calculate.div(f1, f2); System.out.println("第" + i + "题:" + f1.toString() + "÷" + f2.toString()); break; } } return result; } }

    Generator类(执行类)

    public class Generator {
    
        public static void main(String[] args) {
            try {
                int op = 0;
                String input;
                int flag = 0;//用于检测用户答对的题目数
                Scanner sc = new Scanner(System.in);
                System.out.println("【四则运算题目生成器】");
                System.out.println("请输入需要的题目数量:");
                int n = sc.nextInt();
                for (int i = 1; i <= n; i++) {
                    Fraction f1 = Dofrac.CreatFrac();
                    Fraction f2 = Dofrac.CreatFrac();
                    op = (int) (Math.random() * 4 + 1);
                    Fraction result = Dofrac.MakeFor(f1, f2, op, i);
                    input = sc.next();
                    while (!Dofrac.check(input)) {
                        System.out.println("输入有误,请重新输入:");
                        input = sc.next();
                    }
    
                    if (input.equals(result.toString())) {
                        System.out.println("回答正确");
                        System.out.println("---------------------------------------------");
                        flag++;
                    } else {
                        System.out.println("回答错误,正确答案是:" + result.toString());
                        System.out.println("---------------------------------------------");
                    }
    
                }
                System.out.println("---------------------------------------------");
                System.out.println("答题完毕,你的正确率为" + 100 * flag / n + "%");
                sc.close();
    
            } catch (Exception e) {
                e.printStackTrace();
            }
    
        }
    }

     测试运行:

     

    PSP表:

    PSP2.1 Personal Software Process Stages Time (%) Senior Student Time (%)
    Planning 计划 5min 30min
    · Estimate 估计这个任务需要多少时间 8min 10min
    Development 开发 2h 1h30min
    · Analysis 需求分析 (包括学习新技术) 10min 8min
    · Design Spec 生成设计文档 0 0
    · Design Review 设计复审 3min 1min
    · Coding Standard 代码规范 0 0
    · Design 具体设计 1h 30min
    · Coding 具体编码 1h 40min
    · Code Review 代码复审 0 0
    · Test 测试(自我测试,修改代码,提交修改) 5min 8min
    Reporting 报告 30min 40min
    · 测试报告 0 0
    · 计算工作量 0 0
    · 并提出过程改进计划 0 0

    总结:

             此次作业整体难度不大,但是刚开始看到题目构思的时候,却一度陷入僵局。也许是因为太久没有编程,很多知识都忘记了,导致刚开始的时候不懂从何下手。在思考了很久,复习了很多以前的知识后,大体上有了思路,但也不是很清晰,想到什么写什么,迷迷糊糊就完成了。中间遇到的BUG也不是很多,但是调试花了很多时间,感觉这是自己编程思想不够系统,对软件的应用也不是很熟悉造成的,根本原因还是在于练习不够,经验不足。希望以后多加练习,可以更加进步。最后感谢老师们和助教的辛勤付出,你们辛苦了!

  • 相关阅读:
    Codeforces Global Round 11
    2018-2019 ICPC, Asia Najing
    Codeforces Round #675 (Div. 2) ABCDE
    AtCoder Regular Contest 104 D(卡常)
    Navigator History Location
    键盘移动div
    键盘事件
    事件的传播
    事件的绑定
    事件的委派
  • 原文地址:https://www.cnblogs.com/lzx84/p/6514048.html
Copyright © 2011-2022 走看看