示例程序:
import java.util.Arrays; import java.util.List; public class NumberTextTest { public static void main(String[] args) { List<String> numbers = Arrays.asList( "1", "123", "123456789", "101", "1001", "100000", "1000300000250000004", "205734908570001", "1348900" ); NumberText nt = NumberText.getInstance(NumberText.Lang.ChineseSimplified); for(String number : numbers) System.out.println(nt.getText(number)); System.out.println("---"); nt = NumberText.getInstance(NumberText.Lang.English); for(String number : numbers) System.out.println(nt.getText(number)); } }
输出结果:
run: 一 一百二十三 一亿二千三百四十五万六千七百八十九 一百零一 一千零一 一十万 一百京零三百兆零二亿五千万零四 二百零五兆七千三百四十九亿零八百五十七万零一 一百三十四万八千九百 --- one one hundred and twenty three one hundred and twenty three million four hundred and fifty six thousand seven hundred and eighty nine one hundred and one one thousand and one one hundred thousand one quintillion three hundred trillion two hundred and fifty million and four two hundred and five trillion seven hundred and thirty four billion nine hundred and eight million five hundred and seventy thousand and one one million three hundred and fourty eight thousand nine hundred BUILD SUCCESSFUL (total time: 0 seconds)
代码如下
/* * Copyright 2012 na.shi.wu.you (raistlic@gmail.com) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import java.util.HashMap; import java.util.Map; /** * This class transfers an integer number into a string : * * <br/> * * <pre>{@code * // an example : * NumberText ns = NumberText.getInstance(NumberText.Lang.EnglishWithDash); * ns.getText(123) // one hundred and twenty-three * ns.getOrdinalText(320) // three hundred and twentieth * }</pre> * * @date 09/02/2012 * @author na.shi.wu.you (raistlic@gmail.com) */ public abstract class NumberText { /*---------------------------------------------------------------------------- * not designed to be inherented outside this file * no public constructors provided, -- use factory method ---------------------------------------------------------------------------*/ private NumberText() {} /** * Exports a {@code NumberText} implementation instance, based on a natural * language argument. {@see Lang} * * @param lang * @return a NumberText instance. */ public static NumberText getInstance(Lang lang) { return lang.instance(); } /** * Transfers an integer number into a String, specifically in which language * depends on the implementation. * <p /> * e.g. in EnglishWithDash, * <p /> * 100 -> one hundred * <br /> * -976083854 -> minus nine hundred and seventy-six million and eighty-three * thousand eight hundred and fifty-four * * @param number the integer number to be transfered * @return the result String */ public final String getText(long number) { return getText(Long.toString(number)); } /** * Transfers an integer number into a String, specifically in which language * depends on the implementation. * <p /> * e.g. in EnglishWithDash, * <p /> * 100 -> one hundred * <br /> * -976083854 -> minus nine hundred and seventy-six million and eighty-three * thousand eight hundred and fifty-four * * @param number the integer number to be transfered * @return the result String */ public abstract String getText(String number); /** * Transfers an integer number into a String of its ordinal representation, * specifically in which language depends on the implementation. * <p /> * e.g. in EnglishWithDash, * <p /> * 100 -> one hundredth * <br /> * 8331125 -> eight million three hundred and thirty-one thousand one * hundred and twenty-fifth * * @param number the integer number to be transfered * @return the result String */ public final String getOrdinalText(long number) { return getOrdinalText(Long.toString(number)); } /** * <p> * Transfers an integer number into a String of its ordinal representation, * specifically in which language depends on the implementation. * </p> * * <p> * e.g. in EnglishWithDash, * <br /><br /> * 100 -> one hundredth * <br /> * 8331125 -> eight million three hundred and thirty-one thousand one * hundred and twenty-fifth * </p> * * @param number the integer number to be transfered * @return the result String */ public abstract String getOrdinalText(String number); /** * This enumeration type is typically named under a natural language * name, and is to mark a specific implementation name; it is used as an * argument to call the factory method * {@link NumberText#getInstance(NumberText.Lang)}. */ public static enum Lang { English (NumberTextEnglishCleanSpaceOnly.INSTANCE), EnglishWithDash (NumberTextEnglish.INSTANCE), ChineseSimplified (NumberTextChinese.SIMPLIFIED), ChineseTraditional (NumberTextChinese.TRADITIONAL), ; private final NumberText instance; private Lang(NumberText instance) { this.instance = instance; } private NumberText instance() { if( instance == null ) throw new UnsupportedOperationException( "Language not supported yet : " + this); return instance; } } abstract int limit(); void checkNumber(String number) { if( !number.matches("-?\\d+") ) throw new NumberFormatException(); int length = number.length(); if( number.startsWith("-") ) length --; if( length > limit() ) throw new UnsupportedOperationException( "The current " + NumberText.class.getSimpleName() + "can only handle numbers up to (+/-)10^" + limit() + "."); } /*---------------------------------------------------------------------------- * EnglishWithDash Implementation ---------------------------------------------------------------------------*/ private static class NumberTextEnglish extends NumberText { private static final NumberText INSTANCE = new NumberTextEnglish(); static enum Connect { Minus ("minus"), Hundred ("hundred"), And ("and"), AfterMinus (" "), AfterNumber (" "), AfterPower (" "), AfterHundred (" "), AfterAnd (" "), AfterTen ("-"), ; final String display; Connect(String display) { this.display = display; } private static boolean isConnect(char c) { return c == ' ' || c == '-'; } } static enum Power { Thousand ("thousand"), // 10 ^ 3 Million ("million"), // 10 ^ 6 Billion ("billion"), // 10 ^ 9 Trillion ("trillion"), // 10 ^ 12 Quadrillion ("quadrillion"), // 10 ^ 15 Quintillion ("quintillion"), // 10 ^ 18 (enough for Long.MAX_VALUE) Sextillion ("sextillion"), // 10 ^ 21 Septillion ("septillion"), // 10 ^ 24 Octillion ("octillion"), // 10 ^ 27 Nonillion ("nonillion"), // 10 ^ 30 Decillion ("decillion"), // 10 ^ 33 Undecillion ("undecillion"), // 10 ^ 36 Duodecillion ("duodecillion"), // 10 ^ 39 Tredecillion ("tredecillion"), // 10 ^ 42 Quattuordecillion ("quattuordecillion"), // 10 ^ 45 Quindecillion ("quindecillion"), // 10 ^ 48 Sexdecillion ("sexdecillion"), // 10 ^ 51 Septendecillion ("septendecillion"), // 10 ^ 54 Octodecillion ("octodecillion"), // 10 ^ 57 Novemdecillion ("novemdecillion"), // 10 ^ 60 Vigintillion ("vigintillion"), // 10 ^ 63 ; final String display; Power(String display) { this.display = display; } } static enum Digit { Zero ("zero", "zeroth", "ten", ""), One ("one", "first", "eleven", "ten"), Two ("two", "second", "twelve", "twenty"), Three ("three", "third", "thirteen", "thirty"), Four ("four", "fourth", "fourteen", "fourty"), Five ("five", "fifth", "fifteen", "fifty"), Six ("six", "sixth", "sixteen", "sixty"), Seven ("seven", "seventh", "seventeen", "seventy"), Eight ("eight", "eighth", "eighteen", "eighty"), Nine ("nine", "nineth", "nineteen", "ninety"), ; final String display, displayOrdinal, plusTen, multiTen; Digit(String display, String displayOrdinal, String plusTen, String multiTen) { this.display = display; this.displayOrdinal = displayOrdinal; this.plusTen = plusTen; this.multiTen = multiTen; } } private static final Map<String, String> _Ordinals; static { _Ordinals = new HashMap<String, String>(); for(Digit d : Digit.values()) _Ordinals.put(d.display, d.displayOrdinal); } @Override int limit() { return 63; } @Override public String getText(String number) { checkNumber(number); StringBuilder builder = new StringBuilder(); buildText(builder, number); return builder.toString(); } @Override public String getOrdinalText(String number) { checkNumber(number); StringBuilder builder = new StringBuilder(); buildText(builder, number); replaceLastTokenWithOrdinal(builder); return builder.toString(); } private void buildText(StringBuilder builder, String number) { assert builder != null; if( number.startsWith("-") ) { builder.append(getConnectDisplay(Connect.Minus)) .append(getConnectDisplay(Connect.AfterMinus)); number = number.substring(1); } int power = 0; while(number.length() > (power + 1) * 3) power++; while(power > 0) { boolean modified = extendToken(builder, number, power * 3); if( modified ) builder.append(getConnectDisplay(Connect.AfterNumber)) .append(getPowerDisplay(Power.values()[power-1])); power--; } extendToken(builder, number, 0); } private boolean extendToken(StringBuilder builder, String number, int suffix) { assert builder != null && suffix < number.length(); int len = number.length() - suffix; int hundreds = len > 2 ? (int)(number.charAt(len-3)-'0') : -1; int tens = len > 1 ? (int)(number.charAt(len-2)-'0') : -1; int inds = (int)(number.charAt(len-1)-'0'); if( hundreds <= 0 && tens <= 0 && inds <= 0 && suffix > 0 ) return false; else if( len > 3 ) builder.append(getConnectDisplay(Connect.AfterPower)); if( hundreds == 0 ) { if( len > 3 && (tens > 0 || inds > 0) ) builder.append(getConnectDisplay(Connect.And)) .append(getConnectDisplay(Connect.AfterAnd)); } else if( hundreds > 0 ) { builder.append(getDigitName(Digit.values()[hundreds])) .append(getConnectDisplay(Connect.AfterNumber)) .append(getConnectDisplay(Connect.Hundred)); if( tens > 0 || inds > 0 ) builder.append(getConnectDisplay(Connect.AfterHundred)) .append(getConnectDisplay(Connect.And)) .append(getConnectDisplay(Connect.AfterAnd)); } if( tens > 1 ) { builder.append(getDigitMultiTen(Digit.values()[tens])); if( inds > 0 ) builder.append(getConnectDisplay(Connect.AfterTen)); } if( tens == 1 ) builder.append(getDigitPlusTen(Digit.values()[inds])); else if( inds > 0 || number.length() == 1 ) builder.append(getDigitName(Digit.values()[inds])); return true; } private void replaceLastTokenWithOrdinal(StringBuilder builder) { assert builder != null && builder.length() > 0; int suffix = builder.length()-1; while( suffix >= 0 && !isConnect(builder.charAt(suffix)) ) suffix--; String lastToken = builder.substring(suffix+1); builder.delete(suffix+1, builder.length()).append(toOrdinal(lastToken)); } String getPowerDisplay(Power power) { assert power != null; return power.display; } String getConnectDisplay(Connect connect) { assert connect != null; return connect.display; } String getDigitName(Digit digit) { assert digit != null; return digit.display; } String toOrdinal(String name) { assert name != null && !name.isEmpty(); String result = _Ordinals.get(name); if( result == null ) { if( name.charAt(name.length()-1) == 'y' ) result = name.substring(0, name.length()-1) + "ieth"; else result = name + "th"; } return result; } String getDigitPlusTen(Digit digit) { assert digit != null; return digit.plusTen; } String getDigitMultiTen(Digit digit) { assert digit != null; return digit.multiTen; } boolean isConnect(char c) { return Connect.isConnect(c); } } /*---------------------------------------------------------------------------- * EnglishWithDash with only Clean Space Connectors ---------------------------------------------------------------------------*/ private static class NumberTextEnglishCleanSpaceOnly extends NumberTextEnglish { private static final NumberText INSTANCE = new NumberTextEnglishCleanSpaceOnly(); @Override String getConnectDisplay(Connect connect) { return connect == Connect.AfterTen ? " " : super.getConnectDisplay(connect); } } /*---------------------------------------------------------------------------- * ChineseSimplified Implementation ---------------------------------------------------------------------------*/ private static class NumberTextChinese extends NumberText { private static final NumberText SIMPLIFIED = new NumberTextChinese(Type.Simplified); private static final NumberText TRADITIONAL = new NumberTextChinese(Type.Traditional); static enum Type { Simplified, Traditional; } static enum Connect { Di ("第", "第"), Fu ("负", "負"), Ling ("零", "零"), Shi ("十", "拾"), Bai ("百", "佰"), Qian ("千", "仟"), ; final String display, displayTraditional; Connect(String display, String displayTraditional) { this.display = display; this.displayTraditional = displayTraditional; } } static enum Power { Wan ("万", "萬"), // 10^4 Yi ("亿", "億"), // 10^8 Zhao ("兆", "兆"), // 10^12 Jing ("京", "京"), // 10^16 (enough for Long.MAX_VALUE) Gai ("垓", "垓"), // 10^20 Zi ("秭", "秭"), // 10^24 Rang ("穰", "穰"), // 10^28 Gou ("沟", "溝"), // 10^32 Jian ("涧", "澗"), // 10^36 Zheng ("正", "正"), // 10^40 Zai ("载", "載"), // 10^44 ; final String display, displayTraditional; Power(String display, String displayTraditional) { this.display = display; this.displayTraditional = displayTraditional; } } static enum Digit { Ling ("零", "零"), // just to occupy this position Yi ("一", "壹"), Er ("二", "贰"), San ("三", "叁"), Si ("四", "肆"), Wu ("五", "伍"), Liu ("六", "陆"), Qi ("七", "柒"), Ba ("八", "捌"), Jiu ("九", "玖"), ; final String display, displayTraditional; Digit(String display, String displayTraditional) { this.display = display; this.displayTraditional = displayTraditional; } } private final Type type; private NumberTextChinese(Type type) { assert type != null; this.type = type; } @Override int limit() { return 44; } @Override public String getText(String number) { checkNumber(number); StringBuilder builder = new StringBuilder(); buildText(builder, number); return builder.toString(); } @Override public String getOrdinalText(String number) { checkNumber(number); StringBuilder builder = new StringBuilder().append(Connect.Di); buildText(builder, number); return builder.toString(); } private void buildText(StringBuilder builder, String number) { assert builder != null; if( number.startsWith("-") ) { builder.append(getConnectDisplay(Connect.Fu)); number = number.substring(1); } int power = 0; while(number.length() > (power + 1) * 4) power++; while(power > 0) { if( extendToken(builder, number, power * 4) ) builder.append(getPowerDisplay(Power.values()[power-1])); power--; } extendToken(builder, number, 0); } private boolean extendToken(StringBuilder builder, String number, int suffix) { assert builder != null && number.length() > suffix; int len = number.length() - suffix; int qian = len > 3 ? (int)(number.charAt(len-4)-'0') : -1; int bai = len > 2 ? (int)(number.charAt(len-3)-'0') : -1; int shi = len > 1 ? (int)(number.charAt(len-2)-'0') : -1; int ind = (int)(number.charAt(len-1)-'0'); boolean nonZero = false; // true if any of the digits is not zero if( qian == 0 ) { if( bai > 0 || shi > 0 || ind > 0 ) builder.append(getConnectDisplay(Connect.Ling)); } else if( qian > 0 ){ builder.append(getDigitDisplay(Digit.values()[qian])) .append(getConnectDisplay(Connect.Qian)); nonZero = true; } if( bai == 0 ) { if( qian > 0 && (shi > 0 || ind > 0) ) builder.append(getConnectDisplay(Connect.Ling)); } else if( bai > 0 ){ builder.append(getDigitDisplay(Digit.values()[bai])) .append(getConnectDisplay(Connect.Bai)); nonZero = true; } if( shi == 0 ) { if( bai > 0 && ind > 0 ) builder.append(getConnectDisplay(Connect.Ling)); } else if( shi > 0 ){ if( number.length() > 2 || shi != 1 ) builder.append(getDigitDisplay(Digit.values()[shi])); builder.append(getConnectDisplay(Connect.Shi)); nonZero = true; } if( ind == 0 ){ boolean addZero = len == 1; for(int i=1; addZero && i<=suffix; i++) { if( number.charAt(i) != '0' ) addZero = false; } if( addZero ) builder.append(getConnectDisplay(Connect.Ling)); } else { builder.append(getDigitDisplay(Digit.values()[ind])); nonZero = true; } return nonZero; } String getConnectDisplay(Connect connect) { assert connect != null; return type == Type.Simplified ? connect.display : connect.displayTraditional; } String getPowerDisplay(Power power) { assert power != null; return type == Type.Simplified ? power.display : power.displayTraditional; } String getDigitDisplay(Digit digit) { assert digit != null; return type == Type.Simplified ? digit.display : digit.displayTraditional; } } }
相关推荐
3. 在转换过程中,使用 `HanDigiStr` 数组和 `HanDiviStr` 数组来存储中文大写数字和中文大写单位。 4. 最后,将转换后的字符串返回。 知识点四: `NumToRMBStr` 函数的实现 `NumToRMBStr` 函数的实现主要包括以下...
标题“数字转汉字大写”暗示我们讨论的是一个将阿拉伯数字转化为中文大写数字的程序或算法。描述中提到的情况,可能是一个程序员在尝试理解并修复一个既有程序时,由于原始代码的注释不足和存在bug,决定重新编写这...
在这个压缩包文件"Class_ZhH"中,我们可以推测它可能包含了一个C#类或方法,用于处理中文数字到大写汉字的转换。由于未提供具体的代码,这里我将提供一个通用的思路: 1. 创建一个字典,键为小写中文数字字符串,值...
sqlserver数字转金额大写,输入数字返回汉字大写
- "d2hz.c":很可能包含主要的数字转中文大写功能的实现,"d" 可能代表 "digit" 或 "decimal",而 "hz" 代表汉字。 - "test2.c":这通常是一个测试程序,用于验证 "d2hz.c" 中的函数是否正确工作,通过输入不同的...
1. 定义中文大写数字的映射表,包括0-9的数字和“元”、“角”、“分”等单位。 2. 检查输入的数字是否有效,例如是否超出合理范围,是否有非法字符等。 3. 将数字进行格式化,通常采用逗号分隔每三位,便于后续处理...
### JS数字转大写知识点详解 #### 一、概述 在日常开发中,尤其是在处理财务相关的数据时,经常需要将数字金额从小写转换为大写形式。这种转换主要用于正式文件或者票据上,使得金额不易被篡改。在给定的代码片段中...
### SAP ABAP 数字金额转中文大写源代码解析及应用 #### 一、背景介绍 在财务系统中,将数字金额转换成中文大写格式是常见需求之一,尤其是在发票开具、合同签订等正式文件中。SAP作为全球领先的企业管理软件之一,...
例如,在某些SQL方言中,我们可以先将日期转换为英文全拼,然后再用自定义的映射表或函数将英文日期转换为中文大写。例如,"2023-01-01" 可能会被转换为 "TWENTY THREE THOUSAND TWO HUNDRED AND THIRTY THREE MINUS...
在这个实验中,`request`对象可能用来接收前端提交的阿拉伯数字,`response`对象则用于返回转换后的大写数字字符串。 接下来是字符串操作,这是实现数字转换的核心部分。在Java中,数字转换为大写字母通常需要通过...
1. **定义汉字数字映射**:首先,我们需要创建一个哈希表或者数组,将数字0-9映射到对应的汉字大写数字。例如: ```delphi var NumberToChinese: array[0..9] of string = ('零', '壹', '贰', '叁', '肆', '伍', '...
中文金额通常以大写汉字表示,如“壹”、“贰”等,而英文金额则遵循特定的语法结构,如"$1,234.56"。转换过程涉及对数字进行拆分、映射和组合。 1. **字符串映射法**:这是最直观的方法,通过创建一个包含数字与...
在中文环境中,我们可以利用`[dbnum2]`数字格式,将数字转换为中文大写数字。 ```excel =TEXT(A1,"[dbnum2]") ``` 这个公式会将单元格A1中的数值转换为中文大写数字,但只限于整数部分。 2. **处理小数点后...
《天乐数字大写转换器_v1.0》是一款专为金融行业设计的实用工具,其主要功能是将数字高效地转换成大写形式,满足财务报表、合同等正式文件中对数字书写规范的需求。这款软件的特点在于其无广告、无插件的纯净体验,...
将数字翻译成英语的JavaScript,可以自动判断出你输入的数字是多大,它会自动拼合,按亿、千万、百万的语法翻译出来,挺实用。
批量实现文件夹和所有目录里的文件英文字母小写转大写,把程序放到需要改的文件同一个目录里就可以
这个压缩包中包含的"人民币金额小写转大写.cmd.txt"文件,就是这样一个批处理脚本,用于将输入的人民币金额小写数字自动转换成大写汉字。由于安全考虑,原文件被暂时改为了TXT格式,使用时需要将其文件扩展名改为"....
默认情况下,Java使用自然排序,即按照字符串的Unicode值进行排序,这对于英文字符和数字来说通常是合适的,但对于中文字符则不是我们期望的排序方式。 为了实现中文、数字和字母的排序,我们需要创建一个`...
3. **自定义转换**:由于标准函数无法满足金额大小写的转换,我们需要自定义一个函数,将每个数字对应到其大写中文字符。这通常涉及到一个数字与中文字符的映射表,例如: - 0 对应 "零" - 1 对应 "壹" - ... - ...
此外,文章还提到了其他相关的PHP函数,如将阿拉伯数字转为中文数字,判断字符是否为中文、英文或数字,以及生成支持中文、字母、数字的验证码等,这些都是PHP处理字符串和字符时常见的实用技巧。这些函数可以帮助...