小学数学题目自动生成器

二年级的孩子需要做大量的三元运算练习题,所以用java代码实现了一个自动生成练习题的功能,下面是具体的java代码

import java.util.Random;
/**
 * 算术问题生成器
 * 
 * 该类用于生成符合特定规则的算术问题,主要特点:
 * 1. 生成包含两个运算符的三元运算问题
 * 2. 支持加减乘除四种基本运算
 * 3. 确保所有运算结果都是整数
 * 4. 根据运算优先级自动添加括号
 * 5. 控制操作数的范围,确保题目难度适中
 */
public class ArithmeticProblemGenerator {
    private static final Random random = new Random();
    private static final int PROBLEM_COUNT = 600;           // 生成题目的数量
    private static final int OPERATOR_COUNT = 4;            // 运算符种类数量(加减乘除)
    private static final int ADD = 0;                       // 加法运算符
    private static final int SUB = 1;                       // 减法运算符
    private static final int MULT = 2;                      // 乘法运算符
    private static final int DIV = 3;                       // 除法运算符
    private static final int MIN_ADD_SUB = 40;              // 加减法操作数的最小值
    private static final int MAX_ADD_SUB = 90;              // 加减法操作数的最大值
    private static final int MIN_MULT_DIV = 3;              // 乘除法操作数的最小值
    private static final int MAX_MULT_DIV = 9;              // 乘除法操作数的最大值
    private static final int MIN_NUM = 3;                   // 所有操作数的最小值
    private static final int MAX_NUM = 100;                 // 所有操作数的最大值
    private static final int LARGE_NUM_THRESHOLD = 81;      // 大数的阈值,超过此值使用加法拆分
    private static final int SMALL_NUM_THRESHOLD = 10;      // 小数的阈值,低于此值使用除法拆分
    private static final int LARGE_NUM_MIN = 20;            // 大数拆分时的最小值
    private static final int MAX_FACTOR = 9;                // 因数的最大值
    private static final int MIN_FACTOR = 2;                // 因数的最小值

    public static void main(String[] args) {
        for (int i = 1; i <= PROBLEM_COUNT; i++) {
            System.out.println(generateProblem());
        }
    }

    private static String generateProblem() {
        ArithmeticProblem problem = new ArithmeticProblem();
        int firstOperator = random.nextInt(OPERATOR_COUNT);
        problem.firstOperator = firstOperator;
        
        if (isAdditionOrSubtraction(firstOperator)) {
            int firstOperand = random.nextInt(MAX_ADD_SUB - MIN_ADD_SUB) + MIN_ADD_SUB;
            int secondOperand = random.nextInt(MAX_NUM - firstOperand - MIN_NUM) + MIN_NUM;
            if (isAddition(firstOperator)) {
                problem.firstOperand = firstOperand;
                problem.secondOperand = secondOperand;
            } else {
                problem.firstOperand = firstOperand + secondOperand;
                problem.secondOperand = secondOperand;
            }
        } else if (isMultiplicationOrDivision(firstOperator)) {
            int firstOperand = random.nextInt(MAX_MULT_DIV - MIN_MULT_DIV) + MIN_MULT_DIV;
            int secondOperand = random.nextInt(MAX_MULT_DIV - MIN_MULT_DIV) + MIN_MULT_DIV;
            if (isMultiplication(firstOperator)) {
                problem.firstOperand = firstOperand;
                problem.secondOperand = secondOperand;
            } else {
                problem.firstOperand = firstOperand * secondOperand;
                problem.secondOperand = secondOperand;
            }
        }
        
        int splitChoice = random.nextInt(2);
        if (splitChoice == 0) {
            NumberSplitter splitter = new NumberSplitter(problem.firstOperand, true, isMultiplicationOrDivision(problem.firstOperator));
            splitter.split();
            problem.thirdOperand = problem.secondOperand;
            problem.secondOperator = problem.firstOperator;
            problem.secondOperand = splitter.secondOperand;
            problem.firstOperand = splitter.firstOperand;
            problem.firstOperator = splitter.operator;
            problem.hasBraceAtFirst = splitter.needBrackets();
        } else {
            NumberSplitter splitter = new NumberSplitter(problem.secondOperand, false, isMultiplicationOrDivision(problem.firstOperator));
            splitter.split();
            problem.secondOperand = splitter.firstOperand;
            problem.thirdOperand = splitter.secondOperand;
            problem.secondOperator = splitter.operator;
            problem.hasBraceAtSecond = splitter.needBrackets();
        }
        
        return problem.toString();
    }

    private static boolean isAddition(int operator) {
        return operator == ADD;
    }

    private static boolean isSubtraction(int operator) {
        return operator == SUB;
    }

    private static boolean isMultiplication(int operator) {
        return operator == MULT;
    }

    private static boolean isDivision(int operator) {
        return operator == DIV;
    }

    private static boolean isAdditionOrSubtraction(int operator) {
        return isAddition(operator) || isSubtraction(operator);
    }

    private static boolean isMultiplicationOrDivision(int operator) {
        return isMultiplication(operator) || isDivision(operator);
    }

    private static String getOperatorSymbol(int operator) {
        return operator == ADD ? "+" : operator == SUB ? "-" : operator == MULT ? "x" : "÷";
    }

    private static class ArithmeticProblem {
        private int firstOperand;      // 第一个操作数
        private int secondOperand;     // 第二个操作数
        private int thirdOperand;      // 第三个操作数
        private int firstOperator;     // 第一个运算符
        private int secondOperator;    // 第二个运算符
        private boolean hasBraceAtFirst;   // 第一个操作数是否需要括号
        private boolean hasBraceAtSecond;  // 第二个操作数是否需要括号

        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder();
            sb.append(hasBraceAtFirst ? "( " : "");
            sb.append(firstOperand).append(" ");
            sb.append(getOperatorSymbol(firstOperator)).append(" ");
            sb.append(hasBraceAtSecond ? "( " : "");
            sb.append(secondOperand).append(" ");
            sb.append(hasBraceAtFirst ? ") " : "");
            sb.append(getOperatorSymbol(secondOperator)).append(" ");
            sb.append(thirdOperand).append(" ");
            sb.append(hasBraceAtSecond ? ") " : "");
            sb.append("=");
            return sb.toString();
        }
    }

    private static class NumberSplitter {
        private int firstOperand;      // 拆分后的第一个操作数
        private int secondOperand;     // 拆分后的第二个操作数
        private int operator;          // 拆分后的运算符
        private int originalNumber;    // 要拆分的原始数字
        private boolean isFirstNumber; // 是否是第一个数
        private boolean isOriginalMultOrDiv;  // 原运算是否是乘除

        public NumberSplitter(int originalNumber, boolean isFirstNumber, boolean isOriginalMultOrDiv) {
            this.originalNumber = originalNumber;
            this.isFirstNumber = isFirstNumber;
            this.isOriginalMultOrDiv = isOriginalMultOrDiv;
        }

        public void split() {
            if (originalNumber > LARGE_NUM_THRESHOLD) {
                this.firstOperand = random.nextInt(originalNumber - 1 - LARGE_NUM_MIN) + LARGE_NUM_MIN;
                this.secondOperand = originalNumber - firstOperand;
                this.operator = ADD;
                return;
            }
            
            if (originalNumber < SMALL_NUM_THRESHOLD) {
                this.secondOperand = random.nextInt(MAX_MULT_DIV - MIN_MULT_DIV) + MIN_MULT_DIV;
                this.firstOperand = this.secondOperand * originalNumber;
                this.operator = DIV;
                return;
            }
            
            int randomOperator = random.nextInt(OPERATOR_COUNT);
            this.operator = randomOperator;
            
            if (isAddition(randomOperator)) {
                this.firstOperand = random.nextInt(originalNumber - 1 - MIN_NUM) + MIN_NUM;
                this.secondOperand = originalNumber - firstOperand;
            } else if (isSubtraction(randomOperator)) {
                this.secondOperand = random.nextInt(MAX_NUM - this.originalNumber - MIN_NUM) + MIN_NUM;
                this.firstOperand = this.secondOperand + this.originalNumber;
            } else if (isMultiplication(randomOperator)) {
                for (int i = MIN_FACTOR; i <= MAX_FACTOR; i++) {
                    if (originalNumber % i == 0 && originalNumber / i <= MAX_FACTOR) {
                        this.firstOperand = i;
                        this.secondOperand = originalNumber / i;
                        return;
                    }
                }
                this.secondOperand = random.nextInt(MAX_NUM - this.originalNumber - MIN_NUM) + MIN_NUM;
                this.firstOperand = this.secondOperand + this.originalNumber;
                this.operator = SUB;
            } else if (isDivision(randomOperator)) {
                this.secondOperand = random.nextInt(MAX_NUM - this.originalNumber - MIN_NUM) + MIN_NUM;
                this.firstOperand = this.secondOperand + this.originalNumber;
                this.operator = SUB;
            }
        }

        public boolean needBrackets() {
            if (isFirstNumber) {
                return (isAddition(operator) || isSubtraction(operator)) && isOriginalMultOrDiv;
            } else {
                return isOriginalMultOrDiv || (isAddition(operator) || isSubtraction(operator));
            }
        }
    }
}

生成的题目示例如下:

5 x ( 56 ÷ 7 ) =
10 + 56 + 28 =
93 + 5 - 18 =
86 - ( 34 - 17 ) =
4 x ( 24 ÷ 6 ) =
3 + 46 + 47 =
76 - 15 ÷ 3 =
90 - 9 + 8 =
12 ÷ 4 x 8 =
20 ÷ ( 40 ÷ 8 ) =
26 + 61 - 47 =
( 66 - 42 ) ÷ 4 =
64 + 27 ÷ 3 =
30 + 64 - 23 =
40 ÷ 8 x 6 =
8 x ( 30 ÷ 5 ) =
75 + ( 80 - 66 ) =
61 - 9 ÷ 3 =
83 - 6 - 15 =
50 + ( 24 + 10 ) =
83 + 63 ÷ 7 =
94 - 17 + 12 =
85 - ( 76 - 34 ) =
3 x 7 ÷ 7 =
79 + 56 ÷ 8 =
79 - 9 + 27 =
16 ÷ ( 28 ÷ 7 ) =
24 ÷ ( 28 ÷ 7 ) =
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值