欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

相关标签: java