50道100以内的加减法口算习题及它的模块化改造
程序员文章站
2022-06-17 18:45:50
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档50道100以内的加减法口算习题及它的模块化改造目录50道100以内的加减法口算习题及它的模块化改造前言一、未经过模块化设计的基础代码1.代码示例2.存在的问题二、分解与模块化1.分解思想2.代码示例三、选择与设计算法1、习题与算式的分离2、算式产生与其约束条件的分离3、加减法算式的分离四、模块化改造后的完整代码前言对50道100以内的加减法口算习题的代码进行模块化改造,使其运用模块化技术进行分解和细化,设由函数组成的、具有一定结...
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
50道100以内的加减法口算习题及它的模块化改造
目录
前言
对50道100以内的加减法口算习题的代码进行模块化改造,使其运用模块化技术进行分解和细化,设由函数组成的、具有一定结构的程序来分离不同的专注点,管理和控制程序的复杂性,使其便亍维护、更新和扩展。提示:以下是本篇文章正文内容
一、未经过模块化设计的基础代码
1.代码示例
/**/
import java.util.Random;
public class BinaryOperation_0 {
public static void main(String[] args) {
int m = 0, n = 0, value = 0;
char o = '+';
Random random = new Random();
int ov = random.nextInt(2); // 0:加号; 1:减号
for (int i = 0; i < 50; i++) {
if(ov == 0) {
o = '+';
do {
m = random.nextInt(101);
n = random.nextInt(101);
value = m + n;
}while(value > 100);
}else {
o = '-';
do {
m = random.nextInt(101);
n = random.nextInt(101);
value = m - n;
}while(value < 0);
}
System.out.println((i+1) + "\t:" + m + o + n + " = " + value);
ov = random.nextInt(2);
}
}
}
2.存在的问题
• 程序没有明确清晰的“算式”、“习题”的含义,没有使用相应的变量、数据结构等程序设计的
方式表达。
• 若干独立的功能集中在一个函数中丌利亍发现和修改程序中的错诨,也丌便扩充程序的功能。
• 程序修改后,每次都要重新设计一些检验的数据,运行程序、观察结果,判断修改过的程序是否正确,我们希望能保留下检测数据、运行结果及其判断,无须改变地反复使用。
• 编程缺乏觃范。
二、分解与模块化
1.分解思想
采用分解的策略对上一版程序进行重构,产生50道100以内的加减法算式习题
- (1)增加一个打印说明 printHeader
- (2)产生加减法算式,并存储在数组里 generateEquations()
- (3)打印输出习题 printExercise
- (4)打印计算结果 printCalculations
2.代码示例
代码如下:
import java.util.Random;
public class BinaryOperation_1 {
static String[] equs = new String[50]; //存储算式集合的数组
static int[] results = new int[50]; // 存储计算结果的数组
public static void main(String[] args) {
printHeader(); //打印说明
generateEquations(); // 产生加减法算式,并存储在数组里
printExercise(); //打印输出习题
printCalculations(); //打印计算结果
}
public static void printHeader() {
System.out.println("----------------------------------------------");
System.out.println("--程序输出50道100以内的加减法算式习题---");
System.out.println("--每次运行可得到一套习题和答案---");
System.out.println("----------------------------------------------");
}
public static void generateEquations() {
int m = 0, n = 0, value = 0;
char o = '+';
Random random = new Random();
int ov = random.nextInt(2); // 0:加号; 1:减号
for (int i = 0; i < 50; i++) {
if(ov == 0) {
o = '+';
do {
m = random.nextInt(101);
n = random.nextInt(101);
value = m + n;
}while(value > 100);
}else {
o = '-';
do {
m = random.nextInt(101);
n = random.nextInt(101);
value = m - n;
}while(value < 0);
}
ov = random.nextInt(2);
equs[i] = "" + m + o + n + " = ";
results[i] = value;
}
}
public static void printExercise() {
for(int i = 0; i < equs.length; i++) {
System.out.println((i+1) + ":\t" + equs[i]);
}
}
public static void printCalculations() {
System.out.println("\n-----以下是习题的答案-------");
for(int i = 0; i < results.length; i++) {
System.out.println((i+1) + ":\t" + results[i]);
}
}
}
三、选择与设计算法
1、习题与算式的分离
概述:
把习题和算式明确地仍代码中抽出,并分别用合适的数据结构表示,有助于各自的设计和实现。而且,不仅一个程序的数据结构具有丌同的组合方式。如果把数据结构连同对它们的操作也都封装到一个模块——最简单的就是函数,那么,包含了数据与操作的这些函数可以作为程序的模块使用。可以提高程序的结构性和可维护性,如可以替换相同功能、不同实现的模块,而不影响程序的功能。
算式:
/**
* 产生一个加法算式
*/
public static int[] generateAnAddEquation(int add_max_value, int max_oprt_value) {
int m, n, v;
int e[] = new int[] {0,0,0,0};
do {
m = generateOperand(max_oprt_value); // 产生一个不超过max_oprt_value的操作数
n = generateOperand(max_oprt_value); // 产生一个不超过max_oprt_value的操作数
v = m + n;
}while(v > add_max_value);
e[0] = m; //第一个操作数
e[1] = n; //第二个操作数
e[2] = 0; //操作符:0--加法;1--减法
e[3] = v; // 计算结果
return e;
}
习题:
/**
* 产生加法算式习题集
*/
public static int[][] generateExerciseOfAdditionEquations(int equ_num,
int add_max_value, int max_oprt_value){
int m, n; //操作数
int e[]; // 算式 //[操作数1,操作数2,操作符,结果]
int[][] exercise = new int[equ_num][4];
int e_index = 0; //目前习题中算式的个数
for(int i = 0; i < equ_num; i++) {
do {
e = generateAnAddEquation(add_max_value, max_oprt_value); //产生一个加法算式
}while(occursIn(e, exercise, e_index)); //判断算式e是否出现在习题exercise中
exercise[e_index++] = e; // 把算式e存放在习题exercise中,游标加1
}
return exercise;
}
2、算式产生与其约束条件的分离
• 考虑到程序的可扩展性、可修改性,例如,允许不止一个加法或减法运算,或者将算式数值范围扩大到500、1000等。
• 分别定义运算数生成函数不约束条件检测函数,对满足一定条件的运算数才生成算式。
•满足100 以内整数”的条件不仅适合两个运算数,也适用于其结果。
代码如下:
final int EQUATION_NUM = 50; // 习题中等式的数量
final int ADD_MAX_VALUE = 100; // 加法算式约束:加法结果的最大值 .
final int MAX_OPRT_VALUE = 99; // 算式约束:操作数的最大值
final int SUB_MIN_VALUE = 0; //减法算式约束:减法结果的最小值
final int NUM_PER_LINE = 5; //打印格式:每行算式个数
int[][] exercise; // 习题集二维数组
3、加减法算式的分离
为了能够产生全加、全减和混合三种类型的习题,应当分别编写加法算式和减法算式函数,然后随机地选择这两种算式,就能生成混合运算的习题。
代码如下:
/* 打印加法算式习题 */
printHeader("--程序输出加法算式的习题--"); // 打印输出信息头
exercise = generateExerciseOfAdditionEquations(EQUATION_NUM,
ADD_MAX_VALUE,MAX_OPRT_VALUE); // 产生加法算式习题
formatAndDisplayExercise(exercise, NUM_PER_LINE); //打印习题
/* 打印减法算式习题 */
printHeader("--程序输出减法算式的习题--"); // 打印输出信息头
exercise = generateExerciseOfSubtractionEquations(EQUATION_NUM,
SUB_MIN_VALUE,MAX_OPRT_VALUE); // 产生加法算式习题
formatAndDisplayExercise(exercise, NUM_PER_LINE); //打印习题
/* 打印加减法混合算式习题 */
printHeader("--程序输出加减法混合算式的习题--"); // 打印输出信息头
exercise = generateExerciseOfAddAndSubEquations(EQUATION_NUM,
ADD_MAX_VALUE,SUB_MIN_VALUE,MAX_OPRT_VALUE); // 产生加法算式习题
formatAndDisplayExercise(exercise, NUM_PER_LINE); //打印习题
四、模块化改造后的完整代码
import java.util.Random;
/**
* 产生加法、减法、混合算式习题
* (1)采用4元素一维数组存放算式,[操作数1,操作数2,操作符,结果],操作符:0--加法;1--减法
* (2)采用二维数组存放习题[equation_num][4]
* (3)产生算式功能模块化
* (4)打印功能模块化
* @author lenovo
*
*/
public class ExerciseGenerator_task3 {
public static void main(String[] args) {
final int EQUATION_NUM = 50; // 习题中等式的数量
final int ADD_MAX_VALUE = 100; // 加法算式约束:加法结果的最大值 .
final int MAX_OPRT_VALUE = 99; // 算式约束:操作数的最大值
final int SUB_MIN_VALUE = 0; //减法算式约束:减法结果的最小值
final int NUM_PER_LINE = 5; //打印格式:每行算式个数
int[][] exercise; // 习题集二维数组
/* 打印加法算式习题 */
printHeader("--程序输出加法算式的习题--"); // 打印输出信息头
exercise = generateExerciseOfAdditionEquations(EQUATION_NUM,
ADD_MAX_VALUE,MAX_OPRT_VALUE); // 产生加法算式习题
formatAndDisplayExercise(exercise, NUM_PER_LINE); //打印习题
/* 打印减法算式习题 */
printHeader("--程序输出减法算式的习题--"); // 打印输出信息头
exercise = generateExerciseOfSubtractionEquations(EQUATION_NUM,
SUB_MIN_VALUE,MAX_OPRT_VALUE); // 产生加法算式习题
formatAndDisplayExercise(exercise, NUM_PER_LINE); //打印习题
/* 打印加减法混合算式习题 */
printHeader("--程序输出加减法混合算式的习题--"); // 打印输出信息头
exercise = generateExerciseOfAddAndSubEquations(EQUATION_NUM,
ADD_MAX_VALUE,SUB_MIN_VALUE,MAX_OPRT_VALUE); // 产生加法算式习题
formatAndDisplayExercise(exercise, NUM_PER_LINE); //打印习题
}
/**
* 产生加法算式习题集
* @param equ_num:习题集中算式的数量
* @param add_max_value:加法结果的最大值
* @param max_oprt_value:操作数的最大值
* @return:返回习题二维数组[equation_num][4]
*/
public static int[][] generateExerciseOfAdditionEquations(int equ_num,
int add_max_value, int max_oprt_value){
int m, n; //操作数
int e[]; // 算式 //[操作数1,操作数2,操作符,结果]
int[][] exercise = new int[equ_num][4];
int e_index = 0; //目前习题中算式的个数
for(int i = 0; i < equ_num; i++) {
do {
e = generateAnAddEquation(add_max_value, max_oprt_value); //产生一个加法算式
}while(occursIn(e, exercise, e_index)); //判断算式e是否出现在习题exercise中
exercise[e_index++] = e; // 把算式e存放在习题exercise中,游标加1
}
return exercise;
}
/**
* 产生减法算式习题集
* @param equ_num:习题集中算式的数量
* @param sub_min_value:减法结果的最小值
* @param max_oprt_value:操作数的最大值
* @return:返回习题二维数组[equation_num][4]
*/
public static int[][] generateExerciseOfSubtractionEquations( int equ_num,
int sub_min_value, int max_oprt_value){
int m, n; //操作数
int e[]; // 算式 //[操作数1,操作数2,操作符,结果]
int[][] exercise = new int[equ_num][4];
int e_index = 0; //目前习题中算式的个数
for(int i = 0; i < equ_num; i++) {
do {
e = generateAnSubtractEquation(sub_min_value, max_oprt_value); //产生一个减法算式
}while(occursIn(e, exercise, e_index)); //判断算式e是否出现在习题exercise中
exercise[e_index++] = e; // 把算式e存放在习题exercise中,游标加1
}
return exercise;
}
/**
* 产生加减法算式习题集
* @param equ_num:习题集中算式的数量
* @param add_max_value:加法结果的最大值
* @param sub_min_value:减法结果的最小值
* @param max_oprt_value:操作数的最大值
* @return:返回习题二维数组[equation_num][4]
*/
public static int[][] generateExerciseOfAddAndSubEquations(int equ_num,
int add_max_value, int sub_min_value, int max_oprt_value){
int m, n; //操作数
int e[]; // 算式 //[操作数1,操作数2,操作符,结果]
int[][] exercise = new int[equ_num][4];
int e_index = 0; //目前习题中算式的个数
int operator; //操作符(随机产生)
Random random = new Random();
for(int i = 0; i < equ_num; i++) {
operator = random.nextInt(2); //0---加法;1---减法
do {
if(operator == 0) { //加法
e = generateAnAddEquation(add_max_value, max_oprt_value); //产生一个加法算式
}else { //减法
e = generateAnSubtractEquation(sub_min_value, max_oprt_value); //产生一个减法算式
}
}while(occursIn(e, exercise, e_index)); //判断算式e是否出现在习题exercise中
exercise[e_index++] = e; // 把算式e存放在习题exercise中,游标加1
}
return exercise;
}
/**
* 产生一个加法算式
* @param add_max_value:加法结果的最大值
* @param max_oprt_value: 操作数的最大值
* @return: 返回一个数组表示的算式[操作数1,操作数2,操作符,结果],操作符:0--加法;1--减法
*/
public static int[] generateAnAddEquation(int add_max_value, int max_oprt_value) {
int m, n, v;
int e[] = new int[] {0,0,0,0};
do {
m = generateOperand(max_oprt_value); // 产生一个不超过max_oprt_value的操作数
n = generateOperand(max_oprt_value); // 产生一个不超过max_oprt_value的操作数
v = m + n;
}while(v > add_max_value);
e[0] = m; //第一个操作数
e[1] = n; //第二个操作数
e[2] = 0; //操作符:0--加法;1--减法
e[3] = v; // 计算结果
return e;
}
/**
* 产生一个减法算式
* @param sub_min_value:减法结果的最小值
* @param max_oprt_value: 操作数的最大值
* @return: 返回一个数组表示的算式[操作数1,操作数2,操作符,结果],操作符:0--加法;1--减法
*/
public static int[] generateAnSubtractEquation(int sub_min_value, int max_oprt_value) {
int m, n, v;
int e[] = new int[] {0,0,0,0};
do {
m = generateOperand(max_oprt_value); // 产生一个不超过max_oprt_value的操作数
n = generateOperand(max_oprt_value); // 产生一个不超过max_oprt_value的操作数
v = m - n;
}while(v < sub_min_value);
e[0] = m; //第一个操作数
e[1] = n; //第二个操作数
e[2] = 1; //操作符:0--加法;1--减法
e[3] = v; // 计算结果
return e;
}
/**
* 产生一个不超过 max_value的随机数
* @param max_value
* @return
*/
public static int generateOperand(int max_value) {
Random random = new Random();
return random.nextInt(max_value+1);
}
/**
* 判断算式在习题中是否重复
* @param eq: 算式[操作数1,操作数2,操作符,结果]
* @param exercise:习题集二维数组
* @param index:目前习题中算式的个数(游标)
* @return:返回布尔值,重复返回1;不重复返回0.
*/
public static boolean occursIn(int[] eq, int[][] exercise, int index) {
boolean found = false;
for(int i = 0; i < index; i++) {
if(isEqual(eq, exercise[i])) {
found = true;
break;
}
}
return found;
}
/**
* 判断两个算式是否相等
* @param eq1:第一个算式 [操作数1,操作数2,操作符,结果]
* @param eq2:第二个算式 [操作数1,操作数2,操作符,结果]
* @return:如果相等,返回1;如果不相等,返回0
*/
public static boolean isEqual(int[] eq1, int[] eq2) {
return (eq1[0] == eq2[0] && eq1[1] == eq2[1] && eq1[2] == eq2[2])
|| (eq1[0] == eq2[1] && eq1[1] == eq2[0] && eq1[2] == eq2[2]);
}
/**
* 按格式打印习题集
* @param exercise: 习题集二维数组[equation_num][4]
* @param num_per_line: 每行显示的算式个数
*/
public static void formatAndDisplayExercise(int[][] exercise, int num_per_line) {
int i, m, n, o, v;
int e[]; //算式数组[操作数1,操作数2,操作符,结果]
for(i = 0; i < exercise.length; i++) {
e = exercise[i];
m = e[0];
n = e[1];
o = e[2];
v = e[3];
if(i % num_per_line == 0) {
System.out.println();
System.out.printf("%2d ~ %2d: ", i+1, i+5);
}
if(o == 0) { //加法算式,操作符:0--加法;1--减法
System.out.printf("%2d + %2d = %3d ", m, n, v);
}else {
System.out.printf("%2d - %2d = %3d ", m, n, v);
}
}
}
/**
* 打印输出提示信息
*
* @param str: 要打印的提示信息
*/
public static void printHeader(String str) {
System.out.println("\n\n------------------------------------");
System.out.println(str);
System.out.println("------------------------------------");
}
}
本文地址:https://blog.csdn.net/weixin_50903128/article/details/109623977