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 使用去掉類型註解即可。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章