中文数字转阿拉伯数字Java优雅实现
支持以下中文数字的解析:“点 廿卅 零一二三四五六七八九 十百千万亿”。
测试代码:
public static void main(String[] args) {// 测试代码testParseChineseNumber("一二三四五", 12345);testParseChineseNumber("二零一二", 2012);testParseChineseNumber("一亿二千万零三万四千五百六十七", 120034567);testParseChineseNumber("一百二十万三千零四十亿五千万零六十万七千八百九十", 120304050607890L);testParseChineseNumber("一万万", 100000000);testParseChineseNumber("一三五七九点二四六八零", 13579.24680);testParseChineseNumber("一万千", Double.NaN);testParseChineseNumber("二二十", Double.NaN);testParseChineseNumber("二十三十", Double.NaN);}
全部程序:
public class ParseChineseNumber {private static final String nums = "零一二三四五六七八九";private static final String units = "十百千万亿";private static final int[] unitsScales = {10, 100, 1000, 10000, 100000000};private static long parseChineseNumberWithoutUnit(String str) {long result = 0L;for (int i = 0; i < str.length(); i++) {char ch = str.charAt(i);int num = nums.indexOf(ch);assert num >= 0;result = result * 10L + num;}return result;}private static double parseChineseNumberWithUnit(String str) {if (!containsUnit(str)) {return parseChineseNumberWithoutUnit(str);}long num = 0L;int lastUnit = units.length();boolean lastIsNum = false;Deque<Long> stack = new ArrayDeque<>();for (int i = 0; i < str.length(); i++) {char ch = str.charAt(i);int unit = units.indexOf(ch);if (unit >= 0) {// 遇到单位if (lastIsNum) {if (unit < lastUnit) {num *= unitsScales[unit];}stack.addLast(num);if (unit >= lastUnit) {if (!compactStack(stack, unit)) {// 单位顺序不符合预期(非法)return Double.NaN;}}} else {assert !lastIsNum;if (unit < lastUnit) {// 单位后跟着更小的单位(非法):二百十return Double.NaN;}if (unit >= lastUnit) {if (!compactStack(stack, unit)) {// 单位顺序不符合预期(非法)return Double.NaN;}}}lastUnit = unit;lastIsNum = false;num = 0L;} else {// 遇到数字if (lastIsNum && num != 0) {if (!containsUnit(str)) {// 遇到连续数字(开头已处理,理论上不会走到这里)return parseChineseNumberWithoutUnit(str);} else {// 遇到连续数字,并且带着单位(非法)return Double.NaN;}}num = nums.indexOf(ch);lastIsNum = true;}}// 边界条件:末尾的个位数字入栈if (lastIsNum) {stack.addLast(num);}// 弹栈,并计算栈中使用数字之和,同时检查数字单位从小到大顺序long total = 0L;while (!stack.isEmpty()) {num = stack.pollLast();if (num <= total) {return Double.NaN;}total += num;}return total;}private static boolean compactStack(Deque<Long> stack, int unit) {long unitNum = unitsScales[unit];long total = 0L;boolean pop = false;while (!stack.isEmpty() && stack.peekLast() <= unitNum) {total += stack.pollLast();pop = true;}if (pop) {total *= unitsScales[unit];stack.addLast(total);return true;}return false;}private static boolean containsUnit(String str) {for (int i = 0; i < str.length(); i++) {char ch = str.charAt(i);int unit = units.indexOf(ch);if (unit >= 0) {return true;}}return false;}public static double parseChineseNumber(String str) {// 可能出现的汉字:点 廿卅 零一二三四五六七八九 十百千万亿str = str.replace("廿", "二十").replace("卅", "三十");int pointOffset = str.indexOf('点');String intPart = str;String decimalPart = "";if (pointOffset >= 0) {intPart = str.substring(0, pointOffset);decimalPart = str.substring(pointOffset + 1);}double intNumber = parseChineseNumberWithUnit(intPart);long decimalNumber = parseChineseNumberWithoutUnit(decimalPart);return intNumber + Double.valueOf("." + decimalNumber);}public static void testParseChineseNumber(String str, double expected) {double actual = parseChineseNumber(str);System.out.println(str + " => " + actual);if (Double.isNaN(expected)) {// NOTE: Double.NaN != Double.NaNassert Double.isNaN(actual) : str + " != " + expected;} else {assert expected == actual : str + " != " + expected;}}public static void main(String[] args) {// 测试代码testParseChineseNumber("一二三四五", 12345);testParseChineseNumber("二零一二", 2012);testParseChineseNumber("一亿二千万零三万四千五百六十七", 120034567);testParseChineseNumber("一百二十万三千零四十亿五千万零六十万七千八百九十", 120304050607890L);testParseChineseNumber("一万万", 100000000);testParseChineseNumber("一三五七九点二四六八零", 13579.24680);testParseChineseNumber("一万千", Double.NaN);testParseChineseNumber("二二十", Double.NaN);testParseChineseNumber("二十三十", Double.NaN);}
}
中文数字转阿拉伯数字Java优雅实现相关推荐
- java 将中文数字转阿拉伯数字
java 将中文数字转为阿拉伯数字 由于项目需求要将中文数字转为阿拉伯数字,找了一些博客有些不满足需求.于是参考了一些博客完成以下代码 /*** 中文数字*/private static char[] ...
- java中文数字改阿拉伯数字_[Java教程]Java实现中文数字转换为阿拉伯数字
[Java教程]Java实现中文数字转换为阿拉伯数字 0 2015-05-19 16:00:20 /** * 中文數字转阿拉伯数组[十万九千零六十 --> 109060] * @author 雪 ...
- java中文数字与阿拉伯数字相互转换
最近有一个业务需要用到中文数字与阿拉伯数字相互转换,废话不多说直接上代码. 中文数字/阿拉伯数字互转第一次完善:https://blog.csdn.net/qq_26896085/article/de ...
- 使用cn2an实现中文数字与阿拉伯数字的相互转换
工作中经常遇到阿拉伯数字转换称为中文数字或者大写金额,在网上搜了下,cn2an口碑较好,遂进行了一番学习. 安装 pip install cn2an 依赖库为setuptools.PyYAML 查看版 ...
- 中文数字与阿拉伯数字的转换
工作中,中文大写数字/金额需要转为阿拉伯数字,原本自己写的解析转换太麻烦. 忽然发现有做好的模块cn2an: 优点: 1.可以直接识别句子中的中文数字,省去写re 2.不同的匹配模式控制精确度 缺 ...
- python数字转中文字符_Python实现中文数字转换为阿拉伯数字的方法示例
本文实例讲述了Python实现中文数字转换为阿拉伯数字的方法.分享给大家供大家参考,具体如下: 一.需求 今天写了三千二百行代码. 今天写了3200行代码. 两行意思相同,只是表达方式不太能够,统一掉 ...
- python数字转换_Python实现中文数字转换为阿拉伯数字的方法示例
本文实例讲述了Python实现中文数字转换为阿拉伯数字的方法.分享给大家供大家参考,具体如下: 一.需求 今天写了三千二百行代码. 今天写了3200行代码. 两行意思相同,只是表达方式不太能够,统一掉 ...
- 中文数字与阿拉伯数字转换(Python)
cn2an 是一个快速转化 中文数字 和 阿拉伯数字 的工具包 相关链接 cn2an工具包Github地址 在线测试平台 install git clone https://github.com/Ai ...
- android数字转汉字,【原创】最精简的中文数字和阿拉伯数字互相转换函数
public class ChineseNumUtils { /** * 中文数字转阿拉伯数字 * (长度不能超过long最大值) * * @param chNum 中文数字 * @return 阿拉 ...
最新文章
- 传说中的CAFEBABE到底在哪儿?
- 06 | 哨兵机制: 主库挂了, 如何不间断服务
- Android Donut SDK 1.6r1 今日发布
- 回调java 简书_Java接口回调机制详解【转】
- java signal handler_JAVA优雅停机的实现
- E20180327-hm
- sql 从一张表修改另一张表
- RocketMQ原理解析-Consumer
- VS2015sql本地服务器为空,详解VS2015自带LocalDB数据库用法实例
- 为Linux发行版安装simsun.ttf
- web端内嵌二维码进行微信登陆
- 战矛在线Java_战矛在线职业选择攻略 最强职业推荐
- CapstoneCS5212|CapstoneCS5218|DP转VGA1080P方案设计| DP转HDMI4K 30Hz方案设计
- revit 对计算机最低配置,Revit2016官方推荐电脑配置要求
- 一步一步实现商城微信小程序(四)
- 华为css与堆叠,FAQ-S7706交换机CSS堆叠连接的线缆是否正确
- 什么是表示学习(representation learning)表征学习 表达学习
- R语言︱SNA-社会关系网络 R语言实现专题(基础篇)(一)
- 按键精灵按键助手x86x64内存插件(安卓内存插件)
- TI芯片TMS320DM642开发