1. 程式人生 > >演算法練習03 把數字轉換成中文

演算法練習03 把數字轉換成中文

題目(2018-11-18)

完成將toChineseNum,可以將數字轉換成中文大寫的表示,處理到萬級別,例如toChineseNum(12345),返回一萬二千三百四十五

實現

將數字按照四位分成一組,存放在輸入中,每一項的處理邏輯其實是相同的,無非是根據最後不同的位置,新增不同的單位即可

分組的過程涉及到了上一個聯絡的內容,將陣列每四位分成一組

在對四位數字組成的一項進行處理時,有一些特殊的情況需要關注

最終的程式碼:

const toChineseNum = (num) => {
  if (typeof num !== 'number') {
    return ''
  }
  if (num === 0) {
    return '零'
  }
  const numberCharacter = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九'],
  textCharacter = ['', '十', '百', '千'],
  wordCharacter = ['', '萬', '億'];

  /**
   * 輸入陣列,返回按照位數分割的陣列
   * @param number 傳入的數字
   * @param range 按照此位數將數字分割
   * @returns {Array} 返回用逗號分隔的陣列
   */
  const splitStr = (number, range = 4) => {
    let str = number.toString();

    const[left] = str.split('.');

    const strArr = left.split('').reverse();

    let result = [];
    for (let i = 0; i < strArr.length; i += range) {
      result.push(strArr.slice(i, i + range).reverse().join(''))
    }
    return result.reverse()
  };

  /**
   * 輸入一個四位數的數字,返回漢字表示
   * @param item
   * @returns {string}
   */
  const getChineseItem = item => {
    let temp = item.toString().split('').reverse().map((value, index) = > {
      // 如果數字是0, 後面的兩次就沒有必要加了,例如102中的0, 就不需要翻譯成為【零十】
      return numberCharacter[value] + (+value === 0 ? '' : textCharacter[index])
    }).reverse();

    // 多個重複的零隻保留一個
    temp = temp.reduce((total, current) => {
      if (total[total.length - 1] === '零' && current === '零') {
        return total
      }
      total.push(current);
      return total
    }, []);

    // 針對12,將結果由[一十二]修正為[十二]
    if (temp.length === 2) {
      temp[0] = temp[0].replace(/一十/, '十')
    }

    // 結尾的零要忽略,針對10,將結果由[十零]修正為[十]
    if (temp[temp.length - 1] === '零') {
      temp.pop()
    }

    return temp.join('')
  };

  let splitArr = splitStr(num).reverse();
  return splitArr.map(v = > getChineseItem(v)).map((v, index) = > v + wordCharacter[index]).reverse().join('');
};