代码
let numMap: any = {
'一': 1,
'二': 2,
'两': 2,
'三': 3,
'四': 4,
'五': 5,
'六': 6,
'七': 7,
'八': 8,
'九': 9,
'零': 0,
}
let unitMap: any = {
'十': 10,
'百': 100,
'千': 1000,
'万': 10000,
'亿': 100000000,
}
function zhToNum(testString:string) {
let num = 0; // 结果
let beforeUnit = Infinity;
// 如果字符串长度为1则直接使用map
// 循环字符串
for (let i = 0; i < testString.length; i++) {
const char = testString[i]; // 第一个获取的一定是数字
let tmpNum = numMap[char]; // 数字
let unitSum = 1; // 单位的乘积 eg:'千万' => 1000*10000
if (i == testString.length - 1) { // 说明最后一个数字没有单位
if(testString[i-1] == '零'){
unitSum = 1;
}else{
unitSum = beforeUnit / 10; // 之前是“万”就加上“千”,千=>百...,考虑'三千二','两千一'的情况
}
}
while (unitMap[testString[i + 1]]) { // 循环找数字之后的单位字符,并相乘,eg:'千万' => 1000*10000
unitSum *= unitMap[testString[++i]]
}
if (beforeUnit > unitSum) { // 判断之前的单位,
beforeUnit = unitSum
tmpNum *= unitSum;
num += tmpNum;
} else { //此时单位比之前的单位大, 主要考虑到'三百一十"万"三百一十'的情况,此时的万的计算方式为数字与单位相乘
beforeUnit = Infinity; // 重置前一个单位
num += tmpNum;
num *= unitSum;
}
}
return num;
}
console.log('一千三百二十一:',zhToNum('一千三百二十一'));
console.log('一千三百二十一万一千三百二十一:',zhToNum('一千三百二十一万一千三百二十一'));
console.log('一千万三百零一:',zhToNum('一千万三百零一'));
console.log('一亿五千万三百:',zhToNum('一亿五千万三百'));
console.log('三万两千一:',zhToNum('三万两千一'));
基本思路
数字*单位 + 数字*单位
特殊处理
'一千三百二十一万一千三百二十一',中间的”万“处理和上面所述整体思路不一样,需要判断该单位之前的单位是否比它小
- 小的话,就应该在计算了1320数字后先加1,再乘以10000。而不是原来的相加
- 大的话说明和原来一样,数字*单位 + 数字*单位
"四千三","三万二",最后一位不带单位时要补最近的单位
'二千零一',若最后一位没有单位时,若倒数第二位为‘零’,则补上单位1
自己做的练习,若有错误,敬请指出。