前言
本文记录一个小的算法,就是中文数字转换成数字算法
实现思路一:
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('一十二亿三千零九十六万三千八百九十七'))