博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
模块化(零):综述
阅读量:5297 次
发布时间:2019-06-14

本文共 10953 字,大约阅读时间需要 36 分钟。

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

一切将从一份 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("答对了,恭喜\n");                } else {                    System.out.println("答错了,加油\n");                }            }            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();            }        }    }}

模块化结束后的版本:

模块化前后的文件图

809218-20170309180713078-294526659.png

809218-20170309180720047-110941505.png

最终类图

809218-20170309202902672-289990400.png

一些中间步骤的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: 模块化完成)

转载于:https://www.cnblogs.com/schaepher/p/6527248.html

你可能感兴趣的文章
三维凸包模板
查看>>
zoj 2432(最长递增上升子序列)
查看>>
uva 10791
查看>>
codeforces Round #440 A Search for Pretty Integers【hash/排序】
查看>>
python的字典(dict)的键值对存储规则
查看>>
more 分页显示文件内容
查看>>
ubuntu18 tensorflow cpu fast_rcnn
查看>>
PageHelper在Mybatis中的使用
查看>>
POJ 1742 Coins
查看>>
Leetcode 589. N-ary Tree Preorder Traversal
查看>>
ADO.Net——增、删、改、查
查看>>
thinking back no11
查看>>
机器学习/深度学习/其他开发环境搭建记录
查看>>
xml.exist() 实例演示
查看>>
判断是否为空然后赋值
查看>>
中标麒麟QT+ODBC+人大金仓开发环境配置
查看>>
Silverlight WCF RIA服务(九)Domain Service 2
查看>>
JSON的结构
查看>>
NopCommerce换主题这件小事
查看>>
zabbix监控日志文件
查看>>