zoukankan      html  css  js  c++  java
  • 模块化(零):综述

    这是一系列模块化文章的开端。

    一切将从一份 JAVA 代码开始。这份代码实现了一个能自动生成小学四则运算题目的命令行 “软件”,满足以下需求:

    • 除了整数以外,还支持真分数的四则运算。例如:1/6 + 1/8 = 7/24
    • 运算符为 +, −, ×, ÷
    • 能处理用户的输入(整数、小数、真分数)
    • 对用户的输入判断对错,并统计正确率

    虽然实现了需求,但是所有的代码都写在 main() 方法里面。

    这一系列的文章演示了将其一步步模块化的过程。

    初始的代码如下:

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.math.RoundingMode;
    import java.text.DecimalFormat;
    import java.util.Scanner;
    public class lastdemo {
        private static int Gcd(int num1, int num2) {// 求最大公约数
            num1 = Math.abs(num1);// 负数取绝对值
            num2 = Math.abs(num2);
            int min = Math.min(num1, num2);
            int maxSubmultiple = 1;
            for (int i = min; i >= 1; i--) {
                if (num1 % i == 0 && num2 % i == 0) {
                    maxSubmultiple = i;
                    break;
                }
            }
            return maxSubmultiple;
        }
        public static void main(String[] args) {
            double count1 = 0;
            BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
            Scanner in1 = new Scanner(System.in);
            System.out.print("请输入你想要作答的题目数量:");
            int N = in1.nextInt();
            System.out.print("请选择你要进行的运算:1.整数;2.真分数;");
            /* Scanner in3 = new Scanner(System.in); */
            int input1 = in1.nextInt();
            if (input1 == 1) {
                for (int i = 1; i <= N; i++) {
                    int a = (int) (Math.random() * 10 + 1);/* 防止出现不好处理的0,很不严谨不可取 */
                    int b = (int) (Math.random() * 10 + 1);
                    int c = (int) (Math.random() * 4);
                    int result = 0;
                    switch (c) {
                        case 0:
                            System.out.print("第" + i + "题" + ": ");
                            System.out.print(a + " + " + b + " = ");
                            result = a + b;
                            break;
                        case 1:
                            if (a < b) {
                                int t = a;
                                a = b;
                                b = t;
                            }
                            System.out.print("第" + i + "题" + ": ");
                            System.out.print(a + " - " + b + " = ");
                            result = a - b;
                            break;
                        case 2:
                            System.out.print("第" + i + "题" + ": ");
                            System.out.print(a + " × " + b + " = ");
                            result = a * b;
                            break;
                        case 3:
                            System.out.print("第" + i + "题" + ": ");
                            if (a < b) {
                                int t = a;
                                a = b;
                                b = t;
                            }
                            if (a % b != 0) {
                                a = (int) (Math.random() * 10 + 1) * b;/* 保证能整除 */
                            }
                            System.out.print(a + " ÷ " + b + " = ");
                            result = a / b;
                            break;
                    }
                    Scanner in2 = new Scanner(System.in);
                    int input = in2.nextInt();
                    if (input == result) {
                        count1++;
                        System.out.println("答对了,恭喜
    ");
                    } else {
                        System.out.println("答错了,加油
    ");
                    }
                }
                System.out.println("True Rate:" + count1 / N);
            }
            else if (input1 == 2) {
                int max = 100;// 控制算式个数
                char[] op = { ' ', '+', '-', '*', '÷' };// 操作符
                int[] No = new int[4];// 操作符地址
                int useNo = 0;// 控制操作符
                int[] num1 = new int[10];// 操作数
                int[] numberArea = { 1, 10 };// 数值范围
                String[] Useranser = new String[max];// 用户输入的答案
                String[] StandardAnswer = new String[max];// 标准答案
                int f = 0;// 控制输出真分数的操作符
                int count = 0;// 统计答题正确的数量
                DecimalFormat decimal = new DecimalFormat("#.##");
                decimal.setRoundingMode(RoundingMode.HALF_UP);
                int fz1 = 1;// 分子通分
                int fz2 = 1;// 分子通分
                int fm2 = 1;// 分母通分
                int result = 0;// 分子计算
                int gcd;// 最大公约数
                int fzZeromark = 0;// 分数除法,分子为0标志位
                int fzZeroMark = 0;//
                String zjfz = new String();// 最简分子
                String zjfm = new String();// 最简分母
                System.out.print("请选择是否需要乘除法算术题(Y or N):");// 是否进行乘除法
                char OPP;// 控制是否需要乘除法
                Scanner in2 = new Scanner(System.in);
                OPP = in2.next().charAt(0);
                if (OPP == 'Y' || OPP == 'y') {
                    useNo = 4;
                } else if (OPP == 'N' || OPP == 'n') {
                    useNo = 2;
                }
                System.out.println("请计算下列真分数计算题。(若无法运算请填入null)");
                System.out.println("***************************************");
                for (int i = 0; i < N; i++) {
                    System.out.print("(" + (i + 1) + ") ");
                    for (int j = 0; j < 2; j++)// (第一个真分数)
                    {
                        num1[j] = (int) (Math.random()
                                * (numberArea[1] - numberArea[0]) + numberArea[0]);// 控制随机数数值
                        if (j == 1) {
                            while (num1[j - 1] > num1[j] || num1[j] == 0) {
                                num1[j] = (int) (Math.random()
                                        * (numberArea[1] - numberArea[0]) + numberArea[0]);// 控制随机数数值
                            }
                        }
                    }
                    for (int j = 2; j < 4; j++)// (第二个真分数)
                    {
                        num1[j] = (int) (Math.random()
                                * (numberArea[1] - numberArea[0]) + numberArea[0]);// 控制随机数数值
                        if (j == 3) {
                            while (num1[j - 1] > num1[j] || num1[j] == 0) {
                                num1[j] = (int) (Math.random()
                                        * (numberArea[1] - numberArea[0]) + numberArea[0]);// 控制随机数数值
                            }
                        }
                    }
                    for (int k = 0; k < 2; k++) {// 符号个数
                        No[k] = (int) (Math.random() * useNo + 1);// 随机产生操作符
                    }
                    for (int h = 0; h < 4; h++) {// 2个真分数
                        if (h % 2 == 0)
                            System.out.print(("(" + num1[h] + "/"));
                        else if (h % 2 == 1) {
                            System.out.print(num1[h] + ")");
                            if (f < 1) {// 控制只输出一个操作符
                                System.out.print(op[No[f]]);
                                f++;
                            } else
                                System.out.println("=");
                        }
                    }
                    f = 0;
                    count = 0;
                    for (int g = 0; g < 1; g++) {
                        fz1 = num1[0] * num1[3];
                        fz2 = num1[1] * num1[2];
                        fm2 = num1[1] * num1[3];// 分母
                        fzZeromark = 0;
                        fzZeroMark = 0;
                        switch (op[No[g]]) {
                            case '+':
                                result = fz1 + fz2;// 分子
                                gcd = Gcd(result, fm2);// 除以公约数得到最简分数
                                zjfz = String.valueOf(result / gcd);
                                zjfm = String.valueOf(fm2 / gcd);
                                break;
                            case '-':
                                result = fz1 - fz2;
                                gcd = Gcd(result, fm2);
                                zjfz = String.valueOf(result / gcd);
                                zjfm = String.valueOf(fm2 / gcd);
                                break;
                            case '*':
                                result = num1[0] * num1[2];
                                gcd = Gcd(result, fm2);
                                if (num1[0] == 0 || num1[2] == 0) {
                                    fzZeroMark = 1;
                                }
                                zjfz = String.valueOf(result / gcd);
                                zjfm = String.valueOf(fm2 / gcd);
                                break;
                            case '/':// 乘以另一个数的倒数
                                result = num1[0] * num1[3];
                                fm2 = num1[1] * num1[2];
                                gcd = Gcd(result, fm2);
                                if (num1[0] == 0 || num1[2] == 0) {
                                    fzZeromark = 1;
                                }
                                zjfz = String.valueOf(result / gcd);
                                zjfm = String.valueOf(fm2 / gcd);
                                break;
                        }
                    }
                    if (fzZeromark == 1) {
                        StandardAnswer[i] = "null";// 当第二个数的分子为零时无法进行除法运算
                    } else if (fzZeroMark == 1) {
                        StandardAnswer[i] = "0";
                    } else if (zjfz == zjfm) {
                        StandardAnswer[i] = "1";
                    } else if (zjfm.equalsIgnoreCase("1")) {
                        StandardAnswer[i] = zjfz;
                    } else {
                        StandardAnswer[i] = zjfz + "/" + zjfm;
                    }
                }
                // 答题模板
                System.out.println("请输入你的答案:");
                for (int i = 0; i < N; i++) {
                    System.out.print((i + 1) + ":");
                    Scanner in3 = new Scanner(System.in);
                    Useranser[i] = in3.next();
                    if (Useranser[i].equals(StandardAnswer[i])) {
                        count++;
                    }
                }
                System.out.println("标准答案是 :    ");
                for (int i = 0; i < N; i++) {
                    System.out.println((i + 1) + ":" + StandardAnswer[i]);
                }
                System.out.println("True rate:"
                        + String.valueOf(decimal
                        .format(((float) count / (float) N) * 100)) + "%");
                System.out.println("**************************************");
            }
            else {
                System.out.println("请输入1或2:");
            }
            if (null != in) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    

    模块化结束后的版本:点此进入

    模块化前后的文件图

    最终类图

    一些中间步骤的commit

    id time commit message tag
    26daf92 03-08 16:03 初始版本 (tag: 从网上获取的最初版本的代码)
    b427867 03-08 20:10 完成变量名的替换 (tag: 完成变量名的替换)
    90e4368 03-08 20:29 调整结构并标记模块
    1cd9230 03-08 20:37 第一层模块化完毕
    d29caed 03-08 21:14 分数加减乘除分支转发函数
    7cf2d6b 03-08 21:20 提取出获取标准答案的部分
    65a6155 03-08 21:50 提取出随机获取分数的部分
    e6541d4 03-08 22:11 提取出分数的输出和随机符号
    0e75eef 03-08 23:24 提取出整数加减乘除;合并整数和分数对于用户输入的处理方式 (tag: 模块提取基本完成)
    a03cae2 03-09 11:35 根据类图创建类 (tag: 根据类图创建初始类)
    1b67b32 03-09 11:53 整数算式生成放到ExpressionGenerator类里面
    7e63cef 03-09 11:54 整数计算放到MyNum里面
    508f063 03-09 12:29 完成Expression的实现
    eb6ef0d 03-09 14:02 添加对Expression为整数表达式的测试;从测试中发现问题并修复
    14c3215 03-09 14:39 简化LastDemo类的整数部分(程序暂时不能正确运行)
    7b61b1c 03-09 15:22 简化LastDemo类的分数部分
    6f8e171 03-09 15:31 实现答案的处理;实现分数表达式的生成
    68f585f 03-09 15:44 简化getExpressionStr()的代码
    bacfb8f 03-09 15:57 抽取读用户输入、输出答案、输出正确率
    3c0bcb7 03-09 16:38 替换加减乘除符号;生成两数相减式子时,保证结果为正
    31317c0 03-09 17:02 修复部分分数除法答案错误的问题;模块化完成; (tag: 模块化完成)
  • 相关阅读:
    MySQL查询缓存
    MySQL复制相关参数详解
    MySQL复制机制
    MySQL数据库的多表查询操作
    MySQL数据库单表查询基本操作及DML语句
    Hadoop大数据系列汇总
    MySQL数据库之日志功能详解
    MySQL数据库扫盲
    MySQL数据库之数据类型及基本使用详解
    MySQL数据库之日志管理
  • 原文地址:https://www.cnblogs.com/schaepher/p/6527248.html
Copyright © 2011-2022 走看看