You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中如何使用随机数遍历数组选取随机运算符构建二叉树

实现思路
  • 你的Plus/Minus/Multi/Divide都是二叉运算符Binop的子类,randOp方法已经传入了左右子节点,只需要根据随机值返回对应运算符类的实例,把左右子节点作为构造参数传入即可
  • 不要在方法内重复创建Random对象,Random默认以系统时间戳为种子,短时间内多次创建会导致生成的随机数重复,建议在类中全局维护一个Random实例复用
  • 随机生成的下标范围要和运算符数量对应,nextInt(n)返回的是[0,n)区间的整数,4个运算符的话取值范围是0~3
关于是否需要switch-case

完全不需要强制使用,两种实现方案都可以,用数组+函数式接口的方案比switch-case可维护性更高,后续新增运算符只需要更新工厂列表即可,不需要修改分支逻辑。

修正后的代码

首先在类中添加全局的Random实例和运算符工厂列表:

import java.util.Random;
import java.util.List;
import java.util.function.BiFunction;

public class TestArithmetic {
    // 全局复用Random实例
    private static final Random RAND = new Random();
    // 运算符工厂列表,存储各个运算符类的构造方法引用
    private static final List<BiFunction<Node, Node, Binop>> OP_FACTORIES = List.of(
        Plus::new,
        Minus::new,
        Multi::new,
        Divide::new
    );

    public static void main(String[] args) {
        // 测试随机生成运算符的二叉树
        Node randomTree = randOp(
            randOp(randConst(), randConst()),
            randOp(randConst(), randConst())
        );
        System.out.println(randomTree + " = " + randomTree.eval());

        // 原有测试代码保留
        Node n = new Plus(new Divide(randConst(), randConst()),
                new Divide(randConst(), randConst()));
        Node nDivide = new Divide(new Plus(randConst(), randConst()),
                new Plus(randConst(), randConst()));
        Node nMulti = new Multi(new Plus(randConst(), randConst()),
                new Plus(randConst(), randConst()));
        Node nMinus = new Minus(new Plus(randConst(), randConst()),
                new Plus(randConst(), new Const(4.4)));

        System.out.println(n + " = " + n.eval());
        System.out.println(nDivide + " = " + nDivide.eval());
        System.out.println(nMulti + " = " + nMulti.eval());
        System.out.println(nMinus + " = " + nMinus.eval());
    }
    
    public static Binop randOp(Node lChild, Node rChild) {
        // 随机取工厂列表的下标,调用构造方法生成对应运算符实例
        int opIndex = RAND.nextInt(OP_FACTORIES.size());
        return OP_FACTORIES.get(opIndex).apply(lChild, rChild);
    } 
    
    public static Const randConst() {
        int max = 20;
        int min =1;
        double randNum = RAND.nextInt(max-min+1) + min;
        return new Const(randNum);
    }
}

如果你偏好switch-case的写法,也可以把randOp改成如下实现,效果完全一致:

public static Binop randOp(Node lChild, Node rChild) {
    int opIndex = RAND.nextInt(4);
    switch (opIndex) {
        case 0: return new Plus(lChild, rChild);
        case 1: return new Minus(lChild, rChild);
        case 2: return new Multi(lChild, rChild);
        case 3: return new Divide(lChild, rChild);
        default: throw new IllegalArgumentException("无效运算符索引");
    }
}
原有代码的问题说明
  • 你原来写的randOpNum.nextInt(4)返回值范围是03,但switch的case写的是14,完全覆盖不到正确的随机值
  • 原来的方法直接返回了空的Binop父类实例,没有返回对应运算符的子类实例,不符合多态调用的要求
  • 每次调用随机方法都新建Random实例,容易出现随机数重复的问题

内容的提问来源于stack exchange,提问作者cookielover1120

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 13:27:03