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

JavaScript乘法表指定范围带条件随机数生成问题及实现方案

JavaScript乘法表随机组合生成实现方案

需求说明

需实现乘法表场景下的带条件随机数生成功能,为2-10的每个乘数生成对应随机被乘数组合,满足指定约束规则。

现有运行问题

  • 生成的数组中存在重复的乘法组合,例如多次出现2×4的条目
  • 每次生成的数组长度不固定
  • 存在乘积重复问题,若同时存在4×7和7×4这类乘积相同的条目,需要替换其中一组为新的符合条件的组合
  • 各乘数的条目生成需满足指定频次规则,例如乘数9的条目最少生成1条,最多不超过3条

预期实现效果

  • 每个乘数对应的组合唯一无重复
  • 每次生成的数组长度固定为18
  • 自动校验乘积唯一性,若新增组合的乘积已在数组中存在则重新生成,且仍符合各乘数的频次约束

问题根因

原有代码存在以下缺陷:

  1. 重复校验逻辑失效:用indexOf判断对象数组中的数值是否存在,对象比对永远返回-1,没有实现任何去重逻辑
  2. 未校验乘积唯一性:只做了基础的被乘数判断,没有校验乘积重复场景
  3. 频次总和无约束:随机生成的各乘数频次总和不固定,直接导致最终数组长度不稳定
  4. 重复场景直接跳过:随机到重复值时没有重试补充,进一步导致数组长度不足

修改后完整代码

const randomNumbersGenerator = () => {
  // 随机整数生成工具
  function getRandomInt(min, max) {
    min = Math.ceil(min);
    max = Math.floor(max);
    return Math.floor(Math.random() * (max - min + 1) + min);
  }

  // 乘数配置:乘数数值、最小生成条数、最大生成条数
  const multiplierConfigs = [
    { val: 2, min: 0, max: 2 },
    { val: 3, min: 0, max: 3 },
    { val: 4, min: 0, max: 3 },
    { val: 5, min: 0, max: 3 },
    { val: 6, min: 1, max: 3 },
    { val: 7, min: 1, max: 3 },
    { val: 8, min: 1, max: 3 },
    { val: 9, min: 1, max: 3 },
    { val: 10, min: 0, max: 2 },
  ];
  const TOTAL_COUNT = 18;
  const MULTIPLICAND_RANGE = [2, 12];

  // 第一步:生成符合总长度要求的各乘数频次
  // 先填充最小生成条数
  const freqMap = {};
  let usedCount = 0;
  multiplierConfigs.forEach(config => {
    freqMap[config.val] = config.min;
    usedCount += config.min;
  });
  // 剩余配额随机分配给还有额度的乘数
  while (usedCount < TOTAL_COUNT) {
    const randomConfig = multiplierConfigs[getRandomInt(0, multiplierConfigs.length - 1)];
    if (freqMap[randomConfig.val] < randomConfig.max) {
      freqMap[randomConfig.val] += 1;
      usedCount += 1;
    }
  }

  // 第二步:生成符合去重要求的组合
  const result = [];
  // 用Set做去重校验,分别存组合标识、乘积
  const existedCombos = new Set();
  const existedProducts = new Set();

  for (const config of multiplierConfigs) {
    const multiplier = config.val;
    const count = freqMap[multiplier];
    for (let i = 0; i < count; i++) {
      let multiplicand, product, comboKey;
      // 重试直到生成符合要求的被乘数
      do {
        multiplicand = getRandomInt(MULTIPLICAND_RANGE[0], MULTIPLICAND_RANGE[1]);
        product = multiplier * multiplicand;
        comboKey = `${multiplier}x${multiplicand}`;
      } while (existedCombos.has(comboKey) || existedProducts.has(product));
      // 存入结果和去重集合
      existedCombos.add(comboKey);
      existedProducts.add(product);
      result.push({
        multiplier,
        generated: multiplicand,
        product
      });
    }
  }

  return result;
};

// 测试调用
console.log(randomNumbersGenerator());

实现说明

  1. 先按约束生成各乘数的生成频次,确保总和固定为18,同时满足每个乘数的最小/最大条数要求
  2. 用两个Set分别存储已生成的组合标识和乘积,实现O(1)效率的重复校验
  3. 生成组合时如果遇到重复的组合或乘积,自动重试直到生成符合要求的条目,保证不会因为重复跳过导致长度不足
  4. 移除了原有代码中多余的乘数11相关逻辑,符合2-10的乘数范围要求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 16:45:07