一个坏掉的番茄
Published on 2017-09-02 11:31 in 暂未分类 with Simon Ma

20194684 + 自动生成四则运算题第一版报告

前提需求

要求:使用C或Java语言完成一个自动生成四则运算试题的程序

软件基本功能如下。

  1. 自动生成10道100以内的2个操作数的四则运算算式(+ - * /),要求运算结果也在100以内
  2. 剔除重复算式。2+3 和 2+3 是重复算式,2+3 和 3+2 不属于重复算式
  3. 题目数量可定制
  4. 相关参数可控制
    1. 是否包含乘法和除法
    2. 操作数数值范围可控
    3. 操作数是否含负数
  5. 生成的运算题存储到外部文件result.txt中

需求分析

某幼儿园,老师要每天出30道加减乘除法题目给孩子做。于是,想写一个脚本完成这件事。

功能设计

  • 基本功能
    • 可配置题目数量
    • 支持加减乘除
    • 可配置操作数范围
    • 支持操作数正负性质
  • 扩展功能
    • 可输出答案
    • 可控制题目中操作数的数量
    • 可配置生成的文件路径
    • 多线程生成方程, 充分利用每个CPU, 更快
    • 完善的错误处理机制

设计实现

项目已开源, 开源地址: https://github.com/Tomotoes/arithmetic-generator

点击此处下载应用

项目中所用到的库如下:

其中 Main 类, 是我最欣赏的代码片段, 可以体现出本人的设计思想

package com.tomotoes;

import lombok.extern.java.Log;
import lombok.val;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * @author Simon
 * @project arithmetic-generator
 * @package com.tomotoes
 * @date 2019/9/7 15:39
 */
@Log
public class Main {
	public static ArrayList<String> results;
	public static Generator generator;
	public static Option option;

	public static List<String> getResult(int amount) {
		generator.setArithmetics(new CopyOnWriteArrayList<>());

		IntStream.range(0, amount).parallel().forEach(generator::generate);
		val arithmetics = generator.getArithmetics();

		Map<String, Double> resultsInArithmetics = new ConcurrentHashMap<>(arithmetics.size());
		arithmetics.parallelStream()
			.filter(arithmetic -> results.parallelStream().noneMatch(result -> result.startsWith(arithmetic)))
			.forEach(arithmetic -> resultsInArithmetics.put(arithmetic, Script.eval(arithmetic)));

		return resultsInArithmetics.entrySet().parallelStream()
			.filter(entry -> entry.getValue() <= option.getBound())
			.map(entry -> entry.getKey() + " = " + entry.getValue())
			.collect(Collectors.toList());
	}

	public static void main(String[] args) {
		option = Commander.parse(args);
		generator = new Generator(option);
		results = new ArrayList<>(option.getAmount());

		int numberOfAttempts = 0;
		val maximumOfAttempts = 30;
		while (results.size() != option.getAmount()) {
			val result = getResult(option.getAmount() - results.size());

			// There may be failures.
			// For example, requiring 1000 arithmetics to be generated, and the maximum number of operands is 2 and the maximum number of operands is 2.
			// Obviously, this is not possible.
			numberOfAttempts = result.size() != 0 ? 0 : numberOfAttempts + 1;
			if (numberOfAttempts == maximumOfAttempts) {
				log.warning("Unable to generate the specified number of arithmetic.");
				return;
			}

			results.addAll(result);
		}

		Loggerr logger = new Loggerr(option.getFilePath());
		results.forEach(logger::log);
	}
}

其中Commander 类用来解析命令行参数, 并配置成 Option 对象

Option 类,是项目的统一配置信息

Generator 类负责生成四则运算方程式

Script类负责生成方程式结果

Logger 类负责打印结果,和保存结果

测试运行

后记

呃.. Java 的轮子真圆~

PSP

PSP2.1 任务内容 计划完成需要时间(min) 实际完成需要时间(min)
Planning 计划 5 10
Estimate 估计时间,规划步骤 5 10
Development 开发 30 145
Analysis 需求分析 5 20
Coding 具体编码 20 120
Test 测试 5 5
Reporting 报告 20 40
Postmortem&Process Improvement Plan 总结改进 20 40
posted @ 2019-09-07 21:53  SimonMa  阅读(385)  评论(3编辑  收藏  举报