js/ts 将数字按照指定的拆分次数进行拆分

代码如下:

/**
 * 将数字拆分为指定数量的子数字数组
 * @param targetNumber 需要拆分的目标数字
 * @param splitCount 拆分次数
 * @returns 拆分后的子数字数组
 */
 private numberSplit(targetNumber: number, splitCount: number): Array<number> {
  // 当前拆分次数
  let currSplitCount = 1,
    // 拆分后的数字
    resultNumbers: Array<number> = [],
    // 当前拆分的数字
    currSplitNumber = targetNumber,
    // 当前拆分的数字 currSplitNumber 被拆分后的子数字
    splitedNumbers: Array<number> = []

  // 循环拆分,如果当前拆分次数小于总拆分次数
  while (currSplitCount < splitCount) {
    // 当前拆分的数字一分为二
    splitedNumbers = this.numberDichotomy(currSplitNumber)
    // 将子数字合并到结果中
    resultNumbers = resultNumbers.concat(splitedNumbers)
    // 累计拆分次数
    currSplitCount++
    // 判断当前拆分次数是否小于总拆分次数,如果是,则继续拆分
    if (currSplitCount < splitCount) {
      // 获取子数字中最大的数字,作为下一次被拆分的数字,等待下一次拆分
      currSplitNumber = Math.max(...splitedNumbers)
      // 如果子数字中最大的数字为1,则停止拆分
      if (currSplitNumber === 1) break
      // 否则,将下次待拆分的数字从结果中移除,因为它会被一分为二的子数字替换
      ArrayHelper.Remove(resultNumbers, currSplitNumber)
    }
  }

  // 累计子数字的和,用于验证是否与目标数字相等
  const totalNumber = resultNumbers.reduce((total, curr) => total += curr, 0)
  console.log('目标数字', targetNumber, '拆分次数', splitCount, '拆分后的数字', resultNumbers.join(','), '子数字累计值', totalNumber, `目标数字 ${targetNumber === totalNumber ? '=' : '≠'} 子数字累计值`)
  return resultNumbers
}

/**
 * 将数字一分为二
 * @param num 目标数字
 * @returns 拆分后的子数字数组
 */
private numberDichotomy(targetNum: number): Array<number> {
  if (targetNum < 2) return [targetNum]
  if (targetNum === 2) return [1, 1]

  // 随机获取 1~目标数字减1之间的数作为子数字1
  const subNum1 = this.randomNum(1, targetNum - 1),
    // 目标数字减子数字1作为子数字2
    subNum2 = targetNum - subNum1
  // 子数字合并成结果
  const resultNumbers = [subNum1, subNum2]
  return resultNumbers
}

/**
 * 生成从 min 到 max 的随机数
 * @param min 最小值
 * @param max 最大值
 * @returns 随机数
 */
private randomNum(min: number, max: number): number {
  switch (arguments.length) {
    case 1:
      return parseInt((Math.random() * min + 1).toString(), 10)
    case 2:
      return parseInt((Math.random() * (max - min + 1) + min).toString(), 10)
    default:
      return 0
  }
}
// 使用
const answers = this.numberSplit(target, step)
console.log(answers)

代码使用 TypeScript 写的,js 使用去掉类型注解即可。

嘴角上扬,记得微笑

Published by

风君子

独自遨游何稽首 揭天掀地慰生平

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注