概述

今天突发奇想, 写一个将数字转换成中文字符串的函数. 并不是将 1234 转成 '1234' , 而是将 1234 转成 '一千二百三十四'.

本来以为很简单, 写下来之后发现还是有些坑的.

尝试

因为我是在写完最终版本, 回过头来整理的这篇文章, 所以中间很多尝试的步骤会有所遗漏. 以下简单整理一下. 如果不想看, 可以直接拉到最后, 看最终的成品.

第一次尝试

在写之前, 首先要寻找中文说话的规律嘛.

  1. 数字的念法: 零一二三四五六七八九
  2. 每一位都有一个对应的权重: 个十百千万

所以我的初步想法是, 将数字的每一位都转成中文然后拼上对应的权重, so easy. 以下为 Python 实现:

# 数字中文
DIGIT_STR_LIST = ['', '一', '二', '三', '四', '五', '六', '七', '八', '九']
# 权重中文
WIGHT_STR_LIST = ['', '十', '百', '千', '万', '十万', '百万', '千万', '亿']def num_to_str(num):# 保存每一位的内容result_list = []# 遍历数字的每一位, 将数组转列表并倒序遍历for wight, digit in enumerate(reversed(list(str(num)))):digit = int(digit)digit_str = DIGIT_STR_LIST[digit] if digit < len(DIGIT_STR_LIST) else ''wight_str = WIGHT_STR_LIST[wight] if wight < len(WIGHT_STR_LIST) else ''# 结果拼接result_list.append(digit_str + wight_str)# 将结果倒序拼接result_list.reverse()return "".join(result_list)

OK, 写的很流畅, 也很简单, 尝试一下.

  • 传参: 1234 , 输出: 一千二百三十四 . 很完美.
  • 五位数试一下: 54321. 输出: 五万四千三百二十一. nice
  • 六位数试一下: 654321 . 输出: 六十万五万四千三百二十一. ???

有问题. 这里问题很明显了, 我将权重直接拼到了每一位的后边, 而十万直接拼上去明显有问题. 正解应该是六十五万四千三百二十一.

到这里, 毫无疑问, 一开始思路就错了, 需要重新改变一下思路了.

第二次尝试

对于654321这个数字.

十万位6没有将十万直接拼到后边, 而是和万位5连起来, 一起组成了六十五万. 再多一个数字呢? 7654321, 就应该是七百六十五万. 我貌似发现规律了, 把数字切分为四个一组就可以了.

再看一下位数多一点的数字: 1-2345-6789. 中文是: 一亿-二千三百四十五万-六千七百八十九 嗯, 和我预想得一毛一样. 大概懂了, 着手改进一下:

# 数字中文
DIGIT_STR_LIST = ['', '一', '二', '三', '四', '五', '六', '七', '八', '九']
# 权重中文
WIGHT_STR_LIST = ['', '十', '百', '千']
# 分组后对应的中文
GROUP_STR_LIST = ['', '万', '亿', '兆']def thousand_list_num_to_str(num_list: list) -> str:"""将4位数字转成字符串:param num_list: 数字列表, 长度不超过4. 索引和数字对应为: 个十百千:return:"""# 保存每一位的内容result_list = []# 遍历数字的每一位, 将数组转列表并倒序遍历for wight, digit in enumerate(num_list):digit = int(digit)digit_str = DIGIT_STR_LIST[digit] if digit < len(DIGIT_STR_LIST) else ''wight_str = WIGHT_STR_LIST[wight] if wight < len(WIGHT_STR_LIST) else ''# 结果拼接result_list.append(digit_str + wight_str)# 将结果倒序拼接result_list.reverse()return "".join(result_list)def num_to_str(num : int) -> str:"""将数组装成中文:param num::return:"""# 将数字切割为每四个一组, 分别进行处理num_list = list(str(num))# 这里为了处理长度不是4整数倍的情况, 提前反转.num_list.reverse()group_num_list = [num_list[i:i+4] for i in range(0, len(num_list), 4)]result_list = []# 遍历每一组, 并产生对应中文输出for group, num_list in enumerate(group_num_list):this_num_str = thousand_list_num_to_str(num_list)group_str = GROUP_STR_LIST[group] if group < len(GROUP_STR_LIST) else ''result_list.append(this_num_str + group_str)result_list.reverse()return ''.join(result_list)

OK! 现在已经可以应对刚才的情况了. 试一下:

  • 654321 -> 六十五万四千三百二十一
  • 321 -> 三百二十一
  • 120 -> 一百二十
  • 10101010 -> 一千百一十万一千百一十 纳尼???
  • 1000 -> 一千百一十 纳尼???

很明显, 问题出在thousand_list_num_to_str 这个函数.

四位数的时候, 0应该是要跳过的.

第三次尝试

我们对thousand_list_num_to_str函数进行简单的改进, 遇到零的时候直接跳过, 不进行处理. 改进后如下(只展示了部分改动的地方):

DIGIT_STR_LIST = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九']def thousand_list_num_to_str(num_list: list) -> str:"""将4位数字转成字符串:param num_list: 数字列表, 长度不超过4. 索引和数字对应为: 个十百千:return:"""# 保存每一位的内容result_list = []# 遍历数字的每一位, 将数组转列表并倒序遍历for wight, digit in enumerate(num_list):digit = int(digit)# 0无输出if digit is 0:continuedigit_str = DIGIT_STR_LIST[digit] if digit < len(DIGIT_STR_LIST) else ''wight_str = WIGHT_STR_LIST[wight] if wight < len(WIGHT_STR_LIST) else ''# 结果拼接result_list.append(digit_str + wight_str)# 将结果倒序拼接result_list.reverse()return "".join(result_list)

OK, 再次尝试.

  • 10101010 -> 一千一十万一千一十 nice!
  • 100 -> 一百 nice!
  • 1210 -> 一千二百一十
  • 1201 -> 一千二百一 纳尼??

这里按照思维, 应该是输出一千二百零一才对. 继续对thousand_list_num_to_str函数进行加工.

第四次尝试

这里thousand_list_num_to_str函数要将零输出, 但是要考虑连续为零的情况(前边的100). 改动后代码如下:

def thousand_list_num_to_str(num_list: list) -> str:"""将4位数字转成字符串:param num_list: 数字列表, 长度不超过4. 索引和数字对应为: 个十百千:return:"""# 保存每一位的内容result_list = []# 遍历数字的每一位, 将数组转列表并倒序遍历for wight, digit in enumerate(num_list):digit = int(digit)if digit is 0:# 个位的0无输出if wight is 0:continue# 连续0无输出elif int(num_list[wight-1]) is 0:continue# 直接拼零result_list.append(ZERO_STR)continuedigit_str = DIGIT_STR_LIST[digit] if digit < len(DIGIT_STR_LIST) else ''wight_str = WIGHT_STR_LIST[wight] if wight < len(WIGHT_STR_LIST) else ''#if digit is 0:wight_str = ''# 结果拼接result_list.append(digit_str + wight_str)# 将结果倒序拼接result_list.reverse()return "".join(result_list)

OK. 尝试一下:

  • 100 -> 一百
  • 1201 -> 一千二百零一 nice
  • 101 -> 一百零一
  • 1000 -> 一千
  • 100000000 -> 一亿万 什么鬼?

后边怎么多了一个?

第五次尝试

有了处理0的经验, so easy, num_to_str这个函数呀加上一个对0的处理就好了. 代码如下(只展示了num_to_str函数):

def num_to_str(num : int) -> str:"""将数组装成中文:param num::return:"""# 将数字切割为每四个一组, 分别进行处理num_list = list(str(num))# 这里为了处理长度不是4整数倍情况, 提前反转.num_list.reverse()group_num_list = [num_list[i:i+4] for i in range(0, len(num_list), 4)]result_list = []# 遍历每一组, 并产生对应中文输出for group, num_list in enumerate(group_num_list):# 若是0, 跳过if int(''.join(num_list)) is 0:continuethis_num_str = thousand_list_num_to_str(num_list)group_str = GROUP_STR_LIST[group] if group < len(GROUP_STR_LIST) else ''result_list.append(this_num_str + group_str)result_list.reverse()return ''.join(result_list)

再次进行尝试:

  • 100000000 -> 一亿 nice!!
  • 0 -> ??? 我的零呢?

第六次尝试

这个判断就粗暴了, 直接在num_to_str的入口处强制判一下0, 改动内容:

ZERO_STR = '零'
def num_to_str(num : int) -> str:if num is 0:return ZERO_STR...

再来:

  • 0 ->

经过我的一番测试, 基本完成.

总结

开始有这个想法的时候, 我想着会很简单, 随便写写咯. 但是当真正开始动手后, 才发现, 事情完全偏离了我的预期. 在写的过程中, 初版只是个很简单的版本, 但是在自己尝试的过程中总是发现各种各样的问题, 甚至有的时候解决了这个问题, 回头一测, 发现原来已经改好的问题有出现了, 唉, 果然还是功力太浅啊. too young, too simple, sometimes naive.

我最终还算是磕磕绊绊的写完了, 不过冥冥之中还是感觉有一些情况没有考虑到, 无妨, 反正这不过是个一路填坑的过程, 再碰到问题, 改就完了.


至此, 代码初步完成, 将完整代码奉上:

# 数字中文
DIGIT_STR_LIST = ['', '一', '二', '三', '四', '五', '六', '七', '八', '九']
# 权重中文
WIGHT_STR_LIST = ['', '十', '百', '千']
# 分组后对应的中文
GROUP_STR_LIST = ['', '万', '亿', '兆']
# 零
ZERO_STR = '零'def thousand_list_num_to_str(num_list: list) -> str:"""将4位数字转成字符串:param num_list: 数字列表, 长度不超过4. 索引和数字对应为: 个十百千:return:"""# 保存每一位的内容result_list = []# 遍历数字的每一位, 将数组转列表并倒序遍历for wight, digit in enumerate(num_list):digit = int(digit)if digit is 0:# 个位的0无输出if wight is 0:continue# 连续0无输出elif int(num_list[wight-1]) is 0:continue# 直接拼零result_list.append(ZERO_STR)continuedigit_str = DIGIT_STR_LIST[digit] if digit < len(DIGIT_STR_LIST) else ''wight_str = WIGHT_STR_LIST[wight] if wight < len(WIGHT_STR_LIST) else ''#if digit is 0:wight_str = ''# 结果拼接result_list.append(digit_str + wight_str)# 将结果倒序拼接result_list.reverse()return "".join(result_list)def num_to_str(num : int) -> str:"""将数组装成中文:param num::return:"""if num is 0:return ZERO_STR# 将数字切割为每四个一组, 分别进行处理num_list = list(str(num))# 这里为了处理长度不是4整数倍情况, 提前反转.num_list.reverse()group_num_list = [num_list[i:i+4] for i in range(0, len(num_list), 4)]result_list = []# 遍历每一组, 并产生对应中文输出for group, num_list in enumerate(group_num_list):# 若是0, 跳过if int(''.join(num_list)) is 0:continuethis_num_str = thousand_list_num_to_str(num_list)group_str = GROUP_STR_LIST[group] if group < len(GROUP_STR_LIST) else ''result_list.append(this_num_str + group_str)result_list.reverse()return ''.join(result_list)

如何将数字转换成口语中的文本串相关推荐

  1. 如何更改计算机上面的图表形式,excel表格数据转换图形-怎么把EXCEL中的一组数字转换成图表形式...

    谁会计算机啊,怎么把word里的表格数据转换成簇状... Excel表格转化成的方式如下: 1.打开EXCEL表格,数据,图表右侧下拉按钮,如图 2.出窗口中选择自己需要的图表,这里以曲面图为例,如图 ...

  2. 如何把Excel中的文本数字转换成数字

    把excel数据导入数据库时,有时要把数据格式统一,把文本数字转换成数字.有三种在excel中直接转换的方法 ,另外一种是宏的方法. 1.数据--分列 (最快) 2.查错 3.输入1,复制--粘贴-- ...

  3. 如何将数据库中text字段中返回的数据转换成数组的形式,并且将字符串的数字转换成数字的形式显示

    如何将数据库中text字段中返回的数据转换成数组的形式,并且将字符串的数字转换成数字的形式显示 数据库text字段 数据库中的text字段在前端 界面返回的时候是成字符串的形式的,类似于下图 那么,在 ...

  4. html 将数字转为汉字,怎么将wps中的数字转换成汉字 wps将数字转换汉字的步骤教程...

    在WPS编辑表格数据时,如果我们想要将表格中的数字全部转换成汉字,该如何转换?方法其实很简单,不过还有很多用户不太清楚转换方法,下面教程之家网为大家分享wps将数字转换汉字的步骤教程,不会转换的朋友可 ...

  5. html把数字转换成日期,表格中如何把数字改为日期 表格中打数字会变成日期是怎么回事?...

    Excel 表格中如何把数字转换成时间? 如何在EXCEl中把数字变成日期格式 如何将EXCEL中的日期格式转换成数值型格式 学生出生年月原格式为1990-03-20现在想将它变成199003舍掉后面 ...

  6. php 货币 2位,php中数字转换成货币格式实现代码

    介绍一个自定函数用来把 数字转换成货币格式有需要的同学可以参考一下本函数.  代码如下 复制代码 function format_money( $STR ) { if ( $STR == " ...

  7. 中文格式_财务必会Excel技巧,将数字转换成中文的5种方式

    你还在纠结如何把数字转换成中文大小写吗?下面和大家一起来学习把数字转换成中文的5种方法. 方式一:NUMBERSTRING函数 语法=NUMBERSTRING(数值,选项) 数值:被转换为中文字符串的 ...

  8. python中将数字转换成二进制数

    python中将数字转换成二进制数 256 128 64 32 16 8 4 2 1 1 0 1 0 1 0 1 1 0 这是快速得到342的方法 在python3.6中快速得到342的方法是使用bi ...

  9. 把数组里的字符串转换成数字或者把数字转换成字符串

    把数组里的字符串转换成数字或者把数字转换成字符串 场景 例:如以下接口返回的'1,2,3' 前端需要转成数组 处理完的数组里面的每一项值都变成的字符串,而我想要的是[1,2,3] 于是就找到了下面的方 ...

最新文章

  1. 疫情过后,对医疗AI行业带来的机遇
  2. java的String构造对象的几种方法以及内存运行过程
  3. Oracle 学习系列之一(表空间与表结构)
  4. ubuntu等linux下自定义设置程序代理工具proxychains简介
  5. smarty调试方法
  6. SpringMVC的请求-获得请求参数-获得集合类型参数2
  7. Alibaba数学竞赛试题与答案汇总(持续更新中)
  8. ###《Effective STL》--Chapter2
  9. Linux下自动化测试环境的搭建
  10. 【渝粤教育】国家开放大学2018年春季 0674-22T财务管理 参考试题
  11. mysql 查外键关联关系 (指定被引用表,查哪些表对其有外键引用)
  12. LeetCode 1550. 存在连续三个奇数的数组
  13. 走近Flex组件系列(四):分组组件(Box)、分割组件(DividedBox)和容器组件(Panel)
  14. 48. 总是包含(#include)正确的头文件
  15. github/tensorflow/tensorflow/contrib/slim/
  16. linux系统开机grub命令修复方法,linux系统GRUB修复
  17. antd table表格删除末页数据,跳回上一页
  18. 如果说《热带风暴》在你身上刮过,你还剩下什么?
  19. GhostXP_SP3电脑装机终极版V9.7 (NTFS版)
  20. 联想升级Win11后触摸板失灵怎么办?

热门文章

  1. ODBG常用快捷键总结
  2. java 打包后 文件资源文件 jar,JAVA打包成JAR无法找到资源文件
  3. 线程中task取消_Rust Async: async-task源码分析
  4. java rhino 运行 js_Mozilla Rhino :如何从Java调用JS函数
  5. python s d是什意思_python里d是什么意思
  6. python 多进程 多核_go/node/python 多进程与多核cpu
  7. 自动补足算法是什么_数据、算法岗的几点经验分享!
  8. 新手学完Java可以面试哪些岗位?
  9. native 真机测试react_react-native真机调试出现Failed to install all
  10. php如何检测键盘按键,js键盘事件,判断按下的是哪个键