packagecn.com.hellowood.spider;importjavax.script.ScriptEngine;importjavax.script.ScriptEngineManager;importjavax.script.ScriptException;importjava.io.File;importjava.io.FileWriter;importjava.io.IOException;importjava.util.ArrayList;importjava.util.List;importjava.util.Random;importjava.util.Scanner;/*** 生成100以内四则运算
*
* 要求:
* 1. 0-100之间的四则运算
* 2. 3-5个运算符
* 3. 运算过程中不允许出现负数和分数
* 4. 系统输入生成的题数量
* 5. 输出到 result.txt 文件中,文件目录为当前classpath
* 6. 文件首行输出学号
*
* 使用穷举随机生成题目,会造成大量的栈内存使用,当生成的问题比较多时有可能失败,
* 可以考虑根据规则反向拼接生成*/
public classCalculateGenerator {private static ScriptEngine scriptEngine = new ScriptEngineManager().getEngineByName("JavaScript");private static final char PLUS = '+';private static final char MINUS = '-';private static final char MULTIPLY = '*';private static final char DIVIDE = '/';private static final char DISPLAY_DIVIDE = '÷';private static final char EQUALS = '=';private static final String DOT = ".";private static final String DOT_REGEX = "\\.";private static final char[] operators ={PLUS, MINUS, MULTIPLY, DIVIDE};private static final Integer MIN_OPERATOR_COUNT = 3;private static final Integer MAX_OPERATOR_COUNT = 5;private static final Integer MIN_CAL_VALUE = 0;private static final Integer MAX_CAL_VALUE = 100;private static final String FILE_NAME = "result.txt";private static final String STUDENT_NO = "STUDENT_NO";private static final String NEW_LINE = "\r\n";private static Random random = newRandom();public static void main(String[] args) throwsScriptException {
System.out.println("请输入要生成的练习题数量:");
Scanner scanner= newScanner(System.in);
Integer expressionCount=scanner.nextInt();
List expressionList = new ArrayList<>();for (int i = 0; i < expressionCount; i++) {
expressionList.add(getNextExpression());
System.out.println(String.format("正在生成第 %s 道题", i));
}
writeExpressionsToFile(expressionList);
System.out.println("生成练习题完成");
}/*** 将练习题输出到文件
*
*@paramexpressionList*/
private static void writeExpressionsToFile(ListexpressionList) {
File file= newFile(FILE_NAME);try (FileWriter fileWriter = newFileWriter(file)) {
fileWriter.append(STUDENT_NO);for(String expression : expressionList) {
fileWriter.append(NEW_LINE);
fileWriter.append(expression);
}
}catch(IOException e) {
e.printStackTrace();
}
}/*** 生成练习题
*
*@return*@throwsScriptException*/
private static String getNextExpression() throwsScriptException {
System.out.println("尝试生成下一道题");//运算符数量
int operatorCount = random.nextInt(MAX_OPERATOR_COUNT + 1 - MIN_OPERATOR_COUNT) +MIN_OPERATOR_COUNT;
StringBuilder expression= newStringBuilder();//运算符
List operatorList =getOperatorList(operatorCount);//运算数
List calValueList = getCalValueList(operatorCount + 1);for (int i = 0; i < operatorList.size(); i++) {
Character operator=operatorList.get(i);
Integer previousCalValue=calValueList.get(i);
Integer nextCalValue= calValueList.get(i + 1);
expression.append(previousCalValue);//除法校验除数不为0且能被整除
if (DIVIDE ==operator) {
calValueList.set(i+ 1, getDivideCalValue(previousCalValue, nextCalValue));
}else if (MINUS ==operator) {//减法校验被减数大于减数//当包含小数点时向下取整
String currentResultString =scriptEngine.eval(expression.toString()).toString();if(currentResultString.contains(DOT)) {
currentResultString= currentResultString.split(DOT_REGEX)[0];
}
Integer currentResult=Integer.valueOf(currentResultString);while (currentResult
nextCalValue= random.nextInt(MAX_CAL_VALUE + 1);
}
calValueList.set(i+ 1, nextCalValue);
}
expression.append(operator);
}
expression.append(calValueList.get(operatorCount));//计算当前结果是否为正整数
String result =scriptEngine.eval(expression.toString()).toString();if (result.contains(DOT) || Integer.valueOf(result) < 0) {
System.out.println("当前题目不符合要求");returngetNextExpression();
}
String currentExpression=expression.append(EQUALS).append(result)
.toString()
.replaceAll(String.valueOf(DIVIDE), String.valueOf(DISPLAY_DIVIDE));returncurrentExpression;
}/*** 获取运算符
*
*@paramoperatorCount
*@return
*/
private static List getOperatorList(intoperatorCount) {
List operatorList = new ArrayList<>();for (int i = 0; i < operatorCount; i++) {
Character operator=operators[random.nextInt(operators.length)];
operatorList.add(operator);
}returnoperatorList;
}/*** 获取运算数
*
*@paramcalValueCount
*@return
*/
private static List getCalValueList(intcalValueCount) {
List calValueList = new ArrayList<>();for (int i = 0; i < calValueCount; i++) {
calValueList.add(random.nextInt(MAX_CAL_VALUE+ 1));
}returncalValueList;
}/*** 当为除法时校验除数不为0且能被整除
*
*@parampreviousCalValue
*@paramnextCalValue
*@return
*/
private static intgetDivideCalValue(Integer previousCalValue, Integer nextCalValue) {if (nextCalValue == 0 || previousCalValue % nextCalValue != 0) {
nextCalValue= random.nextInt(MAX_CAL_VALUE) + 1;returngetDivideCalValue(previousCalValue, nextCalValue);
}returnnextCalValue;
}
}