zoukankan      html  css  js  c++  java
  • 个人作业1

    ——四则运算题目生成程序(基于控制台)

    源代码地址:https://git.coding.net/pyj76566/Homework.git

    a.需求分析:

     自动生成小学四则运算题目的命令行 “软件”,满足以下需求:   

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

    b.功能设计:

      基本满足上述的功能

    c.设计实现:

      本程序是通过java来实现的,一共有四个类和一个执行类。Fraction类表示分数,RandomGenerator类表示随机生成式子的类;User类表示用户访问类;Calculator类表示计算类。通过new一个User的实例提醒用户输入题数,这个输入函数中实例化一个RandomGenerator对象,生成一个等式。而RandomGenerator类的计算通过Calculator类,内部的参数是Fraction类型的。

    d.代码说明:

      Fraction类表示的是分数这个类,只有两个属性:分子和分母,重要的函数有:makeItProper():对随机传进参数化简的功能,public Fraction(String trim):还有其中一个构造函数是对传入分数字符串生成一个Fraction实例;RandomGenerator类表示的是随机生成一个式子的类,属性:两个分数、一个结果分数、操作符的下标,操作符的数组,重要函数有:getRandomPara():随机生成一个分数,calResult():计算等式的结果;Calculator类内部都是静态的方法,通过传入两个Fraction类的参数,返回计算后的Fraction;User类属性有:rightNum和totalNum,方法有两个:getCorrectRate()方法和userInput()方法。

    具体代码:

    Fraction类: 

     1 package component;
     2 
     3 public class Fraction {
     4     private int numerator;
     5     private int divisor;
     6 
     7     public Fraction() {
     8         super();
     9     }
    10 
    11     public Fraction(int numerator, int divisor) {//构造出对象时就对其进行化简
    12         this.numerator = numerator;
    13         this.divisor = divisor;
    14         makeItProper();
    15     }
    16 
    17     public Fraction(String trim) {//利用正则表达式对其检测,并且分离字符串,生成Fraction对象,考虑分母为0的情况
    18         if (trim.trim().matches("0")) {
    19             numerator = 0;
    20             divisor = Integer.MAX_VALUE;
    21         } else if (trim.trim().matches("[0-9]+")) {
    22             numerator = Integer.parseInt(trim);
    23             divisor = 1;
    24         } else if (trim.trim().matches("[0-9]+/[0-9]+")) {
    25             String[] result = trim.split("/");
    26             numerator = Integer.parseInt(result[0].trim());
    27             if (Integer.parseInt(result[1].trim()) != 0)
    28                 divisor = Integer.parseInt(result[1].trim());
    29             else {
    30                 System.out.println("what you inputed is valid~!");
    31                 divisor = Integer.MAX_VALUE;
    32             }
    33 
    34         } else {
    35             System.out.println("what you inputed is valid~!");
    36         }
    37     }
    38 
    39     public int getNumerator() {
    40         return numerator;
    41     }
    42 
    43     public void setNumerator(int numerator) {
    44         this.numerator = numerator;
    45     }
    46 
    47     public int getDivisor() {
    48         return divisor;
    49     }
    50 
    51     public void setDivisor(int divisor) {
    52         this.divisor = divisor;
    53     }
    54 
    55     public static int commonDivisor(int m, int n) {//计算最大公约数,可以用作化简和通分
    56         while (m % n != 0) {
    57             int temp = m % n;
    58             m = n;
    59             n = temp;
    60         }
    61         return n;
    62     }
    63 
    64     public void makeItProper() {//通过计算出的最大公约数进行化简
    65         int commondivisor = Fraction.commonDivisor(numerator, divisor);
    66         this.numerator = numerator / commondivisor;
    67         this.divisor = divisor / commondivisor;
    68     }
    69 
    70     @Override
    71     public boolean equals(Object obj) {//覆盖equals函数,当且仅当分子和分母都相等,才返回true
    72         // TODO Auto-generated method stub
    73         if (obj instanceof Fraction)
    74             return this.numerator == ((Fraction) obj).numerator && this.divisor == ((Fraction) obj).divisor;
    75         return false;
    76     }
    77 
    78     @Override
    79     public String toString() {//对其格式化输出,唯一特殊的是整数
    80         if (numerator % divisor == 0) {
    81             return String.format("%d", numerator / divisor);
    82         }
    83         return numerator + "/" + divisor;
    84     }
    85 }
    Fraction

    RandomGenerator类: 

     1 package component;
     2 
     3 import java.util.Random;
     4 
     5 public class RandomGenerator {
     6     protected Fraction para1;
     7     protected Fraction para2;
     8     protected Fraction result;//直接计算出结果
     9     protected int operator;//通过下标来确定符号
    10     protected final String[] operators = { "+", "-", "×", "÷" };
    11 
    12     public RandomGenerator() {//对分数和计算符号进行随机化
    13         para1 = this.getRandomPara();
    14         para2 = this.getRandomPara();
    15         operator = (new Random()).nextInt(4);
    16     }
    17 
    18     public Fraction getRandomPara() {//随机分数
    19         Random r = new Random();
    20         int m = r.nextInt(20) + 1;
    21         int n = r.nextInt(20) + 1;
    22         if (r.nextBoolean()) {
    23             return new Fraction(m * n, n);
    24         } else {
    25             while (m > n) {
    26                 m = r.nextInt(20) + 1;
    27                 n = r.nextInt(20) + 1;
    28             }
    29             return new Fraction(m, n);
    30         }
    31     }
    32 
    33     public Fraction getPara1() {
    34         return para1;
    35     }
    36 
    37     public void setPara1(Fraction para1) {
    38         this.para1 = para1;
    39     }
    40 
    41     public Fraction getPara2() {
    42         return para2;
    43     }
    44 
    45     public void setPara2(Fraction para2) {
    46         this.para2 = para2;
    47     }
    48 
    49     public Fraction calResult() {
    50         switch (operator) {
    51         case 0:
    52             result = Calculator.addFraction(para1, para2);
    53             break;
    54         case 1:
    55             checkSubValue();//减法考虑结果为负数,如果是,则交换参数
    56             result = Calculator.subFraction(para1, para2);
    57             break;
    58         case 2:
    59             result = Calculator.mulFraction(para1, para2);
    60             break;
    61         case 3:
    62             result = Calculator.devideFraction(para1, para2);
    63             break;
    64         }
    65         return result;
    66     }
    67 
    68     public void checkSubValue() {//考虑两个数的大小
    69         int lcm = (para1.getDivisor() * para2.getDivisor())
    70                 / Fraction.commonDivisor(para1.getDivisor(), para2.getDivisor());
    71         int numerator1 = (lcm / para1.getDivisor()) * para1.getNumerator();
    72         int numerator2 = (lcm / para2.getDivisor()) * para2.getNumerator();
    73         if (numerator1 < numerator2) {
    74             Fraction temp = new Fraction(para1.getNumerator(), para1.getDivisor());
    75             para1.setNumerator(para2.getNumerator());
    76             para1.setDivisor(para2.getDivisor());
    77             para2.setNumerator(temp.getNumerator());
    78             para2.setDivisor(temp.getDivisor());
    79         }
    80     }
    81 
    82     @Override
    83     public String toString() {
    84         if (operator == 1) {
    85             checkSubValue();
    86         }
    87         return para1 + " " + operators[operator] + " " + para2 + " = ";
    88     }
    89 }
    RandomGenerator

    Caculator类:

     1 package component;
     2 
     3 public class Calculator {//加减乘除的计算,唯一特殊的是減法的結果为0,额外考虑
     4     public static Fraction addFraction(Fraction para1, Fraction para2) {
     5         int lcm = (para1.getDivisor() * para2.getDivisor())
     6                 / Fraction.commonDivisor(para1.getDivisor(), para2.getDivisor());
     7         int numerator1 = (lcm / para1.getDivisor()) * para1.getNumerator();
     8         int numerator2 = (lcm / para2.getDivisor()) * para2.getNumerator();
     9         return new Fraction(numerator1 + numerator2, lcm);
    10     }
    11 
    12     public static Fraction subFraction(Fraction para1, Fraction para2) {
    13         int lcm = (para1.getDivisor() * para2.getDivisor())
    14                 / Fraction.commonDivisor(para1.getDivisor(), para2.getDivisor());
    15         int numerator1 = (lcm / para1.getDivisor()) * para1.getNumerator();
    16         int numerator2 = (lcm / para2.getDivisor()) * para2.getNumerator();
    17         return (numerator1 == numerator2) ? new Fraction("0") : new Fraction(numerator1 - numerator2, lcm);
    18     }
    19 
    20     public static Fraction mulFraction(Fraction para1, Fraction para2) {
    21         return new Fraction(para1.getNumerator() * para2.getNumerator(), para1.getDivisor() * para2.getDivisor());
    22     }
    23 
    24     public static Fraction devideFraction(Fraction para1, Fraction para2) {
    25         return new Fraction(para1.getNumerator() * para2.getDivisor(), para1.getDivisor() * para2.getNumerator());
    26     }
    27 }
    Calculator

    User类: 

     1 package component;
     2 
     3 import java.util.Scanner;
     4 
     5 public class User {
     6     private int rightNum = 0;//正确的数目
     7     private int totalNum = 0;//总数目
     8 
     9     public String getCorrectRate() {//计算正确率
    10         if (totalNum == 0)//0的情况特殊,另外输出
    11             return "0.0%";
    12         return String.format("%s %.2f %s", "The correct rate is :", (((double) rightNum) / totalNum) * 100, "%");
    13     }
    14 
    15     public void userIntput(String arg) {//用户输入函数,由于输入之前已经检测过,无需再检测
    16         Scanner sc = null;
    17         String temp;
    18         temp = arg.trim();
    19         totalNum = Integer.parseInt(temp);
    20         for (int i = 0; i < totalNum; i++) {
    21             RandomGenerator rg = new RandomGenerator();
    22             System.out.println("******************************************************");
    23             System.out.print(rg);
    24             sc = new Scanner(System.in);
    25             if (sc.hasNextLine()) {
    26                 Fraction result = new Fraction((sc.nextLine()));
    27                 if (result.equals(rg.calResult())) {
    28                     this.rightNum++;
    29                     System.out.println(String.format("%20s", "right!"));
    30                 } else {
    31                     System.out.print(String.format("%20s", "false!"));
    32                     System.out.println("   **the correct answer is:" + rg.calResult());
    33 
    34                 }
    35 
    36             }
    37         }
    38         System.out.println("******************************************************");
    39         System.out.println(
    40                 "Finished! The total questions are:" + this.totalNum + ",and the right questions are:" + this.rightNum);
    41         System.out.println(this.getCorrectRate());
    42     }
    43 
    44 }
    User

    执行类: 

     1 package component;
     2 
     3 public class GeneratorTester {
     4     public static void main(String[] args) {//对输入参数提示和限制
     5         User u = new User();
     6         String num = null;
     7         if (args.length > 0) {
     8             if (args[0].trim().equals("-n") && args.length == 2 && args[1].matches("[0-9]+")) {
     9                 num = args[1];
    10                 u.userIntput(num);
    11             } else
    12                 System.out.println("Parameter formating valid! The standard format is -n digital");
    13         } else {
    14             System.out.println("No defined parameter");
    15         }
    16     }
    17 }
    GeneratorTester

    e.测试运行:

    1.首先对控制台输入的时候 进行参数检测:

    2.对用户的输入的结果进行检测

    PSP表:

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

    小结:

      这次作业难度不高,但是也花费了我挺久的时间,主要是我没有对这个题目进行全面的认识,而且没有好好规划,所以造成了“超时”完工。虽然题目很简单,但是在思考过程中还是得考虑很多东西,比如说分母不为0的问题,减法减出分数的控制问题,覆盖Fraction的equals()问题等等。不过“阿超”完成这个程序的速度也太快了吧,20分钟?看来我的经验还是有很多不足。还有就是拓展性的问题,就以Java来说,设计好类与类之间的关系十分重要,对你的维护以及功能拓展有很大的便捷,不然就十分有可能重新设计,导致工作量增加。所以我觉得可以去看一些关于程序设计的书。至于本程序的扩展,我暂时考虑到的是多项的扩展,因为RandomGenerator类是一个等式,如果要增加项数的话,可以考虑再写一个类Decorator,它和RandomGenerator一起继承一个抽象类,假设是Component,这个类有两个属性,String description 和 Fraction result,表示它的式子和最后的结果,抽象方法有getDecription()和getResult();而Decorator类中有Component引用属性,假设是obj,当要实现抽象类的方法时,getResult()返回的是obj.CalReult()与Decorator类的Fraction引用属性的计算值,至于符号就随机生成,这样当new Decorator(obj)时,getResult()可以得到新的结果,同理getDescription(),至于实现,其实没有这么简单,还要考虑随机生成的问题,以及Decorator类这个新生成后缀的符号和obj内符号之间优先级的问题,总之还是要注意很多的。

     

    2017-03-02 15:24:38

  • 相关阅读:
    (转)UML类图关系(泛化 、继承、实现、依赖、关联、聚合、组合)
    (转)使用 Document!X 为自己的dll生成一个漂亮的说明文档
    我的游戏学习日志42——游戏机制设计(2)
    我的游戏学习日志41——游戏机制设计(1)
    我的游戏学习日志40——游戏概念设计(2)
    我的游戏学习日志39——游戏概念设计(1)
    我的游戏学习日志38——游戏性的评估标准(2)
    我的游戏学习日志37——游戏性的评估标准(1)
    我的游戏学习日志36——游戏结构(小结)
    我的游戏学习日志35——游戏结构(4)
  • 原文地址:https://www.cnblogs.com/pyj76566/p/6488954.html
Copyright © 2011-2022 走看看