1

【小算法】实现一个将中文数字转换成阿拉伯数字的函数

 3 years ago
source link: https://www.haorooms.com/post/chinesenum_tranform_num
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

本文记录一个小的算法,就是中文数字转换成数字算法

实现思路一:

1、从中文数字中逐个识别数字和权位组合

2、根据权位和数字倍数对应关系,计算出每个数字和权位组合值

3、最后求和得出结果

function ChineseToNumber(chnString) {
    const CHN_CHAR_LENGTH = 1;

    const chnNumChar = ["零", "一", "二", "三", "四", "五", "六", "七", "八", "九"];
    const chnUnitChar = ["", "十", "百", "千"]
    const chnUnitSection = ["", "万", "亿", "万亿"]
    const chnValuePair = [
      ["十", 10, false], //  [0] name中文权位名 [1] 10的倍数值 value  [2]secUnit 是否是节权位
      ["百", 100, false],
      ["千", 1000, false],
      ["万", 10000, true],
      ["亿", 100000000, true],
    ]
          //  主要算法
      let rtn = 0;
      let section = 0;
      let number = 0;
      let secUnit = false;
      let pos = 0;
    // 中文数字转换数字,如果返回-1,表示这是一个权位字符。
    function ChineseToValue(chnStr) {
      for (let val = 0; val < chnNumChar.length; val++) {
        if (chnStr == chnNumChar[val]) {
          return val;
        }
      }
      return -1;
    }
    //  chnValuePair 表得到权位对应的10的倍数。
    function ChineseToUnit(chnStr) {
      // console.log(chnStr)
      for (let unit = 0; unit < chnValuePair.length; unit++) {
        if (chnStr == chnValuePair[unit][0]) {
          secUnit = chnValuePair[unit][2];
          // console.log(secUnit)
          return chnValuePair[unit][1];
        }
    }

    return 1;
  }

    while (pos < chnString.length) {
    let num = ChineseToValue(chnString.substr(pos, CHN_CHAR_LENGTH));
    // console.log("num:",num)
    if (num >= 0) // 数字还是单位
    {
        number = num;
        pos += CHN_CHAR_LENGTH;
        if (pos >= chnString.length) //如果是最后一位数字 直接结束
        {
        section += number;
        rtn += section;
        break;
        }
    } else {
        let unit = ChineseToUnit(chnString.substr(pos, CHN_CHAR_LENGTH));
        // console.log("unit",unit,secUnit)
        if (secUnit) //是节权位说明一个节已经结束
        {
        section = (section + number) * unit;
        rtn += section;
        section = 0;
        } else {
        section += (number * unit);
        }
        number = 0;
        pos += CHN_CHAR_LENGTH;
        if (pos >= chnString.length) {
        rtn += section;
        break;
        }
    }
    }

    return rtn;
}

const testPair = [
   [ 0,"零" ],
    [ 1,"一" ],
    [ 2,"二" ],
    [ 3,"三" ],
    [ 4,"四" ],
    [ 5,"五" ],
    [ 6,"六" ],
    [ 7,"七" ],
    [ 8,"八" ],
    [ 9,"九" ],
    [ 10,"一十" ],
    [ 11,"一十一" ],
    [ 110,"一百一十" ],
    [ 111,"一百一十一" ],
    [ 100,"一百" ],
    [ 102,"一百零二" ],
    [ 1020,"一千零二十" ],
    [ 1001,"一千零一" ],
    [ 1015,"一千零一十五" ],
    [ 1000,"一千" ],
    [ 10000,"一万" ],
    [ 20010,"二万零一十" ],
    [ 20001,"二万零一" ],
    [ 100000,"一十万" ],
    [ 1000000,"一百万" ],
    [ 10000000,"一千万" ],
    [ 100000000,"一亿" ],
    [ 1000000000,"一十亿" ],
    [ 1000001000,"一十亿零一千" ],
    [ 1000000100,"一十亿零一百" ],
    [ 200010,"二十万零一十" ],
    [ 2000105,"二百万零一百零五" ],
    [ 20001007,"二千万一千零七" ],
    [ 2000100190,"二十亿零一十万零一百九十" ],
    [ 1040010000,"一十亿四千零一万" ],
    [ 200012301,"二亿零一万二千三百零一" ],
    [ 2005010010,"二十亿零五百零一万零一十" ],
    [ 4009060200,"四十亿零九百零六万零二百" ],
    [ 4294967295,"四十二亿九千四百九十六万七千二百九十五" ]

]

//  测试用例
function  testChineseToNumber()
{
    for(let i = 0; i < testPair.length; i++)
    {
        let  num = ChineseToNumber(testPair[i][1]);
        console.log(num == testPair[i][0]);
    }
}

testChineseToNumber();
// 控制台打印结果 :39 true

实现思路二

1、将中文数字转换成阿拉伯数字

2、将中文权位转换成10的倍数

function transform(str) {
    const numChar = {
        '零':0,
        '一':1,
        '二':2,
        '三':3,
        '四':4,
        '五':5,
        '六':6,
        '七':7,
        '八':8,
        '九':9
    };
    const levelChar = {
        '十':10,
        '百':100,
        '千':1000,
        '万':10000,
        '亿':100000000,
    };
    let ary = Array.from(str)
    let temp = 0
    let sum = 0
    for(let i = 0; i < ary.length; i++) {
        let char = ary[i]
        if(char === '零') continue
        if (char === '亿' || char === '万') {
            sum += temp * levelChar[char]
            temp = 0
        } else {
            let next = ary[i + 1]
            if(next && next !== '亿' && next !== '万') {
                temp += numChar[char] * levelChar[next]
                i++
            } else {
                temp += numChar[char]
            }
        }
    }
    return sum + temp
}

console.log(transform('一十二亿三千零九十六万三千八百九十七'))

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK