如何将快速将数字转为文字比如说 1 => 一,2=> 二, ..., 15=》十五我当前想的是把中文存到一个数组中
$arr = ['一','二','三','四','五','六','七','八','九','十'];
不过这样也太麻烦了 如何将输入数字转换为中文,有没有更简单的方式?
最终实现的结果是这样的:输入 12输出
一二三四五六七八九十十一十二
认证高级PHP讲师
雷雷
如果你能用文字将数字的转化过程描述清楚,那么写代码就是个翻译的过程。
算法其实是业务逻辑很奇怪的业务逻辑而已,重点在于分析这个业务逻辑
阿拉伯数字转中文数字,小学没毕业也会写,脑子里一定有一套方法去完成这个转化过程。所以这里的考察重点就是,对问题的抽象过程。要抽象的准确,首先得对问题本身有一个全面的分析了解,找出规律。比数字转化过程中,0什么时候叫十,什么时候叫零。这个过程,在脑子里执行的太自然了,以至于去分析它的情况,找出规律,都还是需要一定能力的。
推荐这篇文章,文章开始的分析就是抽象过程,对编程很重要
下面是 JavaScript 的实现
JavaScript
汉字显式地指定了 数的阶 比如 一百零一 里面有百这个阶 (个十百千万)
一百零一
2 >>>> 二个 2 >>>> 二个 10 >>>> 一十 >>>> 十10 >>>> 一十 >>>> 十
2
二个
10
一十
十
16 >>>> 一十 六个 >>>> 十六
16
六个
十六
105 >>>> 一百 零十 五个 >>>> 一百零五
105
一百
零十
五个
一百零五
1024 >>>> 一千 零百 二十 四个 >>>> 一千零二十四
1024
一千
零百
二十
四个
一千零二十四
可以看到它的表示法可以看成是 值 + 阶 的形式。
值 + 阶
此外满足以下条件的时候 需要省略阶或者值
需要省略阶或者值
10 对应 一十 写作 十 10 对应 一十 写作 十 110 对应 一百一十零个 写作 一百一十110 对应 一百一十零个 写作 一百一十 .... 等等
110
一百一十零个
一百一十
根据以上思考 应该得出的编程思路是这样的:
输入数字 n
n
把 n 映射到一个数组 tokens 上。 比如 8 变成 ["八"], 101 变成 ["一", "零", "一"] 映射到一个数组 tokens 上。 比如 8 变成 ["八"], 101 变成 ["一", "零", "一"]
tokens
8
["八"]
101
["一", "零", "一"]
添加阶 101 变成 ["一", "百", "十", "零", "一", "个"]
["一", "百", "十", "零", "一", "个"]
筛选 比如 一百十零一个 变成最简形式 一百十零一个 变成最简形式 一百零一
一百十零一个
// 数字到汉字的映射表 var mapHans = ['零', '一','二','三','四','五','六','七','八','九','十']; // 用 n 得到汉字 输入 0 得到 '零' var getHans = n => mapHans[n]; // 数字长度到汉字数级的映射表 var mul = ['十', '百', '千', '万'] // ['i', 'love', 'my', 'wife'] >>>> ilovemywife var arr2str = arr => arr.join(''); // 输入 5 产生 [1, 2, 3, 4, 5] var arrGenerator = n => ( new Array(n).fill(0).map((e, idx) => idx + 1) )
先实现 大于 10 的 数字映射到汉字的数制 上
大于 10
数字映射到汉字的数制
比如输入 101 返回 101 返回 一百零一
利用上面写的工具函数去做会快些
var toHans = n => { // 比如输入 101 返回 ['一', '零', '一'] var tokens = n.toString().split('').map(getHans); // 对数阶的处理 如果上一步得到 ['一', '零', '一'] // 那么at就是 ['百', '十'] var at = mul.slice(0, tokens.length - 1).reverse(); // 归约 return tokens.reduce((acc, cur) => { acc.push(cur); acc.push( at.shift() ) return acc; // 这个reduce将会把 tokens 和 at 耦合在一块 // ['一', '零', '一'] 和 ['百', '十'] 耦合就是: // ['一', '百', '零', '十', '一', undefined] // 下一步的两个 filter 就是要剔除多余的项 }, []).filter(e => e !== undefined).filter((e, idx, its) => { if (e === '零'){ if (idx === its.length - 1) { // 针对 10 >>>> [一 十 零] 这种情况 return false; } else { // 针对 101 >>>> [一 百 零 十 一] 这种情况 its[idx + 1] = null; } } else if (idx === 0 && e === '一' && its[idx + 1] === '十'){ // 针对 12 >>>> [一 十 二] 这种情况 return false; } // 下面还可以再添加。。 不过应该没了。 return e; }); };
简单的测试 测试转化 2 4 6 8 16 32 ... 成 二 四 八 十六 三十二 ...
4
6
32
二
四
八
三十二
// 2 的 n 次方 var twotwotwo = n => ( new Array(n).fill(2).reduce((acc, cur, idx) => { acc = acc * cur; return acc; }, 1) ) // 打印机 var logger = (item, idx) => console.log(`第 ${idx + 1} 个:`, item); // test code function test4toHans(n) { var res = arrGenerator(n).map(twotwotwo).map(toHans).map(arr2str); res.forEach(logger); }
.... 从 1 到 n
var main = n => { var numbers = arrGenerator(n); return numbers.map(toHans).map(arr2str); }
测试
https://github.com/wilon/php-...
PHP数字转为汉字描述,人民币大写
支持千亿级别的数,修改 ws 数组可以无限扩充,修改cns数组为繁体可以用于人民币大写
<?php function IntToString($num) { $cns = ['零','一','二','三','四','五','六','七','八','九']; $ws = ['','十','百','千','万','十','百','千','亿','十','百','千']; $str = ''; foreach (array_reverse(str_split((string)$num,1)) as $key => $value) $str .= $ws[$key].$cns[$value]; $temp = '';//反转字符串 for($i = strlen($str)-1; $i>=0; $i--) $temp .= mb_substr($str,$i,1,'utf-8'); return $temp; } echo IntToString(231231251237); ////二千三百一十二亿三千一百二十五万一千二百三十七
附上思路/a/11...
雷雷
如果你能用文字将数字的转化过程描述清楚,那么写代码就是个翻译的过程。
算法其实是业务逻辑很奇怪的业务逻辑而已,重点在于分析这个业务逻辑
阿拉伯数字转中文数字,小学没毕业也会写,脑子里一定有一套方法去完成这个转化过程。所以这里的考察重点就是,对问题的抽象过程。要抽象的准确,首先得对问题本身有一个全面的分析了解,找出规律。比数字转化过程中,0什么时候叫十,什么时候叫零。这个过程,在脑子里执行的太自然了,以至于去分析它的情况,找出规律,都还是需要一定能力的。
推荐这篇文章,文章开始的分析就是抽象过程,对编程很重要
雷雷
如何将快速将数字转为文字
比如说 1 => 一,2=> 二, ..., 15=》十五
我当前想的是把中文存到一个数组中
不过这样也太麻烦了 如何将输入数字转换为中文,有没有更简单的方式?
最终实现的结果是这样的:
输入 12
输出
下面是
JavaScript
的实现观察汉字的数字表示
汉字显式地指定了 数的阶 比如
一百零一
里面有百这个阶 (个十百千万)2
>>>>二个
2
>>>>二个
10
>>>>一十
>>>>十
10
>>>>一十
>>>>十
16
>>>>一十
六个
>>>>十六
105
>>>>一百
零十
五个
>>>>一百零五
1024
>>>>一千
零百
二十
四个
>>>>一千零二十四
可以看到它的表示法可以看成是
值 + 阶
的形式。此外满足以下条件的时候
需要省略阶或者值
根据以上思考 应该得出的编程思路是这样的:
输入数字
n
把
n
映射到一个数组tokens
上。 比如8
变成["八"]
,101
变成["一", "零", "一"]
映射到一个数组tokens
上。 比如8
变成["八"]
,101
变成["一", "零", "一"]
添加阶
101
变成["一", "百", "十", "零", "一", "个"]
筛选 比如
一百十零一个
变成最简形式一百十零一个
变成最简形式一百零一
工具函数
实现
先实现
大于 10
的数字映射到汉字的数制
上比如输入
101
返回101
返回一百零一
利用上面写的工具函数去做会快些
简单的测试 测试转化
2
4
6
8
16
32
... 成二
四
八
十六
三十二
...遍历数字
.... 从 1 到 n
测试
https://github.com/wilon/php-...
PHP数字转为汉字描述,人民币大写
支持千亿级别的数,修改 ws 数组可以无限扩充,修改cns数组为繁体可以用于人民币大写
附上思路
/a/11...