• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

幻锁

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

PSP四则运算

  1. 题目要求:能自动生成小学四则运算题目,且每一道题目的运算结果不能为负。

  2. 工具清单:Java,Js,Maven,Tomcat,MySQL

  3. PSP表格
    预计耗时(分钟) 实际耗时(分钟)
Planning 计划 20 20
Estimate 估计这个任务需要多少时间 5 5
Development 开发 80 90
Analysis 需求分析 10 10
Design Spec 生成设计文档 / /
Design Review 设计复审(和同事审核设计文档) / /
Coding Standerd 代码规范(为目前的开发制定合适的规范) / /
Design 具体设计 30 30
Coding 具体编码 100 100
Code Review 代码复审 10 15
Text 测试(自测,修改代码,提交修改) 20 20
Reporting 报告 20 20
Text Report 测试报告 10 10
Size Measurement 计算工作量 5 5
Postmortem & Process Improvement Plan 事后总结,并提出过程改进计划 5 5
Sum 合计 305 330

4.运行代码

设置默认配置:

RandomFormula类的无参构造方法,用来设置默认值。numberTotal运算数数量设置为2,formulaToal运算式数量设置为10,numberRange数字范围设置为100,maxResult运算结果的最大范围不超过100的绝对值,includeMulAndDiv包含乘除设置为false,includeNegNum设置为false。

public RandomFormula() {
		this.numberTotal = 2;
		this.formulaTotal = 10;
		this.numberRange = 100;
		this.maxResult = 100;
		this.includeMulAndDiv = false;
		this.includeNegNum = false;
}
2 设置自定义配置:

RandomFormula类的有参构造方法,用来根据需求初始化。

public RandomFormula(int numberTotal, int formulaTotal, int numberRange, int maxResult, boolean includeMulAndDiv,
			boolean includeNegNum) {
		this.numberTotal = numberTotal;
		this.formulaTotal = formulaTotal;
		this.numberRange = numberRange;
		this.maxResult = maxResult;
		this.includeMulAndDiv = includeMulAndDiv;
		this.includeNegNum = includeNegNum;
}
3 产生随机运算数和随机运算符:

getRandomNumber方法用来产生随机数,getRandomOperator方法用来产生随机运算符。

/**
* 获取随机数
* 
* @return 返回一个指定范围内的数字
*/
public int getRandomNumber() {
	Random rand = new Random();
	if (this.includeNegNum) {
		return (rand.nextInt(this.numberRange) + 1) * (rand.nextDouble() > 0.5 ? 1 : -1);
	} else {
		return rand.nextInt(this.numberRange) + 1;
	}
}
/**
* 得到一个随机的运算符
* 
* @return返回运算符
*/
public String getRandomOperator() {
	Random rand = new Random();
	String[] operations = { "+", "-", "*", "/" };
	return operations[rand.nextInt((this.includeMulAndDiv == true) ? 4 : 2)];
}
4 生成四则运算:

根据配置,generateFormula方法生成一道四则运算,如果isNegNum方法判断包含负数,则负数加括号。generateFormulas生成指定数量的四则运算,用HashSet来存储,可以自动去重算式。

/**
* 生成算式
* 
* @return 返回算式
*/
public String generateFormula() {
	String formula = "";
	for (int i = 0; i < this.numberTotal; i++) {
		if (i >= this.numberTotal - 1) {
			formula += isNegNum(this.getRandomNumber());
			continue;
		}
		formula += isNegNum(this.getRandomNumber()) + " " + this.getRandomOperator() + " ";
	}
	return formula;
}
/**
* 生成算式集合
* 
* @return
*/
public HashSet<String> generateFormulas() {
	HashSet<String> set = new HashSet<String>();
	while (set.size() <= this.formulaTotal) {
		String formula=this.generateFormula();
		if(this.maxResult>=this.generateAnswer(formula))
		set.add(formula);
	}
	return set;
}
/**
* 若负数,加括号
* 
* @param num
* @return
*/
public String isNegNum(int num) {
	if (num < 0) {
		return "(" + num + ")";
	}
	return "" + num;
}
5 计算算式的值:

generateAnswer遍历HashSet的算式,compare判断运算符的优先级。根据栈的“先进后出”的特性,若是数字,则入栈;若是字符,判断优先级,优先级高则直接入栈;优先级低,则出栈数字和字符,进入compute计算,然后将结果入栈。如此,来计算算式的值。

/**
* 生成算式结果
* 
* @param formula
* @return
*/
public int generateAnswer(String formula) {
	int length = 0;
	String[] formulaArr = formula.split(" ");
	String operators = "+-*/";
	Stack<Integer> opNumbers = new Stack<Integer>();
	Stack<String> opOperators = new Stack<String>();
	opOperators.add("#");//字符栈中存储个#号,防止栈空
	while (length < formulaArr.length) {
		String op = formulaArr[length++];
		if (operators.indexOf(op) > -1) {// 若是运算符,判断优先级
			String sign = opOperators.peek();
			int priority = compare(op, sign);// 要入栈的跟栈顶的相比
			if (priority >= 0) {// 如果要入栈的运算符高或者相等,出栈两个数字,和之前的运算符,计算后,将数字入栈,将字符入栈
				opNumbers.add(compute(opOperators, opNumbers));
				opOperators.add(op);
			} else {// 入栈运算符优先级低,直接入栈
				opOperators.add(op);
			}
			continue;
		}
		// 若是数字,则入栈
		opNumbers.add(Integer.parseInt(op.replace("(", "").replace(")", "")));
	}
	while (opOperators.peek() != "#") {
		opNumbers.add(compute(opOperators, opNumbers));
	}
	return opNumbers.pop();
}
/**
* 比较运算优先级
* 
* @return
 */
public int compare(String operator1, String operator2) {
	int res = 0;
	switch (operator1) {
	case "+":
	case "-":
		if (operator2.equals("+") || operator2.equals("-") || operator2.equals("*") || operator2.equals("/")) {
			res = 1;
		} else {
			res = -1;
		}
		break;
	case "*":
	case "/":
		if (operator2.equals("*") || operator2.equals("/")) {
			res = 1;
		} else {
			res = -1;
		}
		break;
	}
	return res;
}
/**
* 算式求值
* 
* @return
*/
public int compute(Stack<String> opOperators, Stack<Integer> opNumbers) {
	int num2 = opNumbers.pop();
	int num1 = opNumbers.pop();
	String _op = opOperators.pop();
	int result = 0;
	switch (_op) {
	case "+":
		result = num1 + num2;
		break;
	case "-":
		result = num1 - num2;
		break;
	case "*":
		result = num1 * num2;
		break;
	case "/":
		result = num1 / num2;
		break;
	}
	return result;
}
6 生成答案:

generateAnswers用来生成相应算式数量的值,用一维数组来存储。

/**
* 生成算式结果数组
* 
* @param set
* @return
*/
public int[] generateAnswers(HashSet<String> set) {
	int[] arr = new int[set.size()];
	int i = 0;
	for (String str : set) {
		arr[i++] = generateAnswer(str);
	}
	return arr;
}
7 打印算式和答案:

outputFormulas和outputAnswers将算式和答案,分别保存到result.txt和answer.txt下,并且输出文件的绝对路径。

/** 输出算式到文件
* @param set
* @return
*/
public String outputFormulas(HashSet<String> set) {
	File file=new File("result.txt");
	try {
		FileWriter fw = new FileWriter(file);
		for (String str : set) {
			fw.write(str + "\n");
		}
		fw.close();
	} catch (Exception e) {
		System.out.println("Error" + e.getMessage());
		System.exit(0);
	}
	return file.getAbsolutePath();
}
	
/** 输出答案到文件
* @param arr
* @return
*/
public String outputAnswers(int[] arr) {
	File file=new File("answer.txt");
	try {
		FileWriter fw = new FileWriter(file);
		for (int i = 0; i < arr.length; i++) {
			fw.write(arr[i]+"\n");
		}
		fw.close();
	} catch (Exception e) {
		System.out.println("Error" + e.getMessage());
		System.exit(0);
	}
	return file.getAbsolutePath();	
}
运行
截图

 

 

 

 

 

 

 

posted on 2021-09-26 18:03  幻锁  阅读(96)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3