Java数字转汉字,数字转大写

网上找了一圈,都不合我意,自己花点时间写了一下。
数字不好,逻辑差了点,性能应该还可以。
如果需要修改为转财务大写或转换为语音文件的,可以简单把汉字改一个就行。

package com.lixor;

import java.util.ArrayList;
import java.util.Collections;

/**
* 数字转中文。最大支持到万亿级别。
*
* @author alex
*
*/
public class Num2CN {
/**
* 单位进位,中文默认为4位即(万、亿)
*/
public int UNIT_STEP = 4;

/**
* 单位
*/
public String[] CN_UNITS = new String[] { "个", "十", "百", "千", "万", "十",
"百", "千", "亿", "十", "百", "千", "万" };

/**
* 汉字
*/
public String[] CN_CHARS = new String[] { "零", "一", "二", "三", "四",
"五", "六", "七", "八", "九" };

/**
* 数值转换为中文字符串
*
* @param num
* 需要转换的数值
* @return
*/
public String cvt(long num) {
return this.cvt(num, false);
}

/**
* 数值转换为中文字符串(口语化)
*
* @param num
* 需要转换的数值
* @param isColloquial
* 是否口语化。例如12转换为'十二'而不是'一十二'。
* @return
*/
public String cvt(long num, boolean isColloquial) {
String[] result = this.convert(num, isColloquial);
StringBuffer strs = new StringBuffer(32);
for (String str : result) {
strs.append(str);
}
return strs.toString();
}

/**
* 将数值转换为中文
*
* @param num
* 需要转换的数值
* @param isColloquial
* 是否口语化。例如12转换为'十二'而不是'一十二'。
* @return
*/
public String[] convert(long num, boolean isColloquial) {
if (num < 10) {// 10以下直接返回对应汉字
return new String[] { CN_CHARS[(int) num] };// ASCII2int
}

char[] chars = String.valueOf(num).toCharArray();
if (chars.length > CN_UNITS.length) {// 超过单位表示范围的返回空
return new String[] {};
}

boolean isLastUnitStep = false;// 记录上次单位进位
ArrayList<String> cnchars = new ArrayList<String>(chars.length * 2);// 创建数组,将数字填入单位对应的位置
for (int pos = chars.length - 1; pos >= 0; pos--) {// 从低位向高位循环
char ch = chars[pos];
String cnChar = CN_CHARS[ch - '0'];// ascii2int 汉字
int unitPos = chars.length - pos - 1;// 对应的单位座标
String cnUnit = CN_UNITS[unitPos];// 单位
boolean isZero = (ch == '0');// 是否为0
boolean isZeroLow = (pos + 1 < chars.length && chars[pos + 1] == '0');// 是否低位为0

boolean isUnitStep = (unitPos >= UNIT_STEP && (unitPos % UNIT_STEP == 0));// 当前位是否需要单位进位

if (isUnitStep && isLastUnitStep) {// 去除相邻的上一个单位进位
int size = cnchars.size();
cnchars.remove(size - 1);
if (!CN_CHARS[0].equals(cnchars.get(size - 2))) {// 补0
cnchars.add(CN_CHARS[0]);
}
}

if (isUnitStep || !isZero) {// 单位进位(万、亿),或者非0时加上单位
cnchars.add(cnUnit);
isLastUnitStep = isUnitStep;
}
if (isZero && (isZeroLow || isUnitStep)) {// 当前位为0低位为0,或者当前位为0并且为单位进位时进行省略
continue;
}
cnchars.add(cnChar);
isLastUnitStep = false;
}

Collections.reverse(cnchars);
// 清除最后一位的0
int chSize = cnchars.size();
String chEnd = cnchars.get(chSize - 1);
if (CN_CHARS[0].equals(chEnd) || CN_UNITS[0].equals(chEnd)) {
cnchars.remove(chSize - 1);
}

// 口语化处理
if (isColloquial) {
String chFirst = cnchars.get(0);
String chSecond = cnchars.get(1);
if (chFirst.equals(CN_CHARS[1]) && chSecond.startsWith(CN_UNITS[1])) {// 是否以'一'开头,紧跟'十'
cnchars.remove(0);
}
}
return cnchars.toArray(new String[] {});
}

public static void main(String[] args) {
String[] testData = ("0,1,2,3,4,5,6,7,8,9,"
+ "10,11,20,91,"
+ "110,102,1234,1023,1002,"
+ "10000,12345,10234,10023,10002,12034,12003,12000,12300,12340,"
+ "100000,123456,102345,200234,100023,100002,120345,120034,120003,120000,123000,123400,123450,"
+ "1000000,1234567,2023456,1002345,3000234,1000023,1000002,1203456,1200345,1200034,1200003,1200000,1230000,1234000,1234500,1234560,"
+ "10000000,12345678,10234567,10023456,10002345,10000234,10000023,12034567,12003456,12000345,12000034,12000003,12000000,12300000,12340000,12345600,12345670,"
+ "1000000000,1234567890,1023456789,1002300078,1000230067,1000023456,1000002345,1203456789,1200345678,1200034567,1200003456,1200000345,1200000034,1200000003,1230000000,1234000000,1234500000,1234560000,1234567000,1234567800,1234567890,"

+ String.valueOf(Integer.MAX_VALUE)

+ ",9223372036854,9002233007200").split(",");
for (String data : testData) {
long num = Long.parseLong(data);

if (num < 0) {
continue;
}

System.out.println(String.format("%-12s \t %s", data,
new Num2CN().cvt(num,true)));

}

}
}



运行结果

0 零
1 一
2 二
3 三
4 四
5 五
6 六
7 七
8 八
9 九
10 十
11 十一
20 二十
91 九十一
110 一百一十
102 一百零二
1234 一千二百三十四
1023 一千零二十三
1002 一千零二
10000 一万
12345 一万二千三百四十五
10234 一万零二百三十四
10023 一万零二十三
10002 一万零二
12034 一万二千零三十四
12003 一万二千零三
12000 一万二千
12300 一万二千三百
12340 一万二千三百四十
100000 十万
123456 十二万三千四百五十六
102345 十万二千三百四十五
200234 二十万零二百三十四
100023 十万零二十三
100002 十万零二
120345 十二万零三百四十五
120034 十二万零三十四
120003 十二万零三
120000 十二万
123000 十二万三千
123400 十二万三千四百
123450 十二万三千四百五十
1000000 一百万
1234567 一百二十三万四千五百六十七
2023456 二百零二万三千四百五十六
1002345 一百万二千三百四十五
3000234 三百万零二百三十四
1000023 一百万零二十三
1000002 一百万零二
1203456 一百二十万三千四百五十六
1200345 一百二十万零三百四十五
1200034 一百二十万零三十四
1200003 一百二十万零三
1200000 一百二十万
1230000 一百二十三万
1234000 一百二十三万四千
1234500 一百二十三万四千五百
1234560 一百二十三万四千五百六十
10000000 一千万
12345678 一千二百三十四万五千六百七十八
10234567 一千零二十三万四千五百六十七
10023456 一千零二万三千四百五十六
10002345 一千万二千三百四十五
10000234 一千万零二百三十四
10000023 一千万零二十三
12034567 一千二百零三万四千五百六十七
12003456 一千二百万三千四百五十六
12000345 一千二百万零三百四十五
12000034 一千二百万零三十四
12000003 一千二百万零三
12000000 一千二百万
12300000 一千二百三十万
12340000 一千二百三十四万
12345600 一千二百三十四万五千六百
12345670 一千二百三十四万五千六百七十
1000000000 十亿
1234567890 十二亿三千四百五十六万七千八百九十
1023456789 十亿二千三百四十五万六千七百八十九
1002300078 十亿零二百三十万零七十八
1000230067 十亿零二十三万零六十七
1000023456 十亿零二万三千四百五十六
1000002345 十亿零二千三百四十五
1203456789 十二亿零三百四十五万六千七百八十九
1200345678 十二亿零三十四万五千六百七十八
1200034567 十二亿零三万四千五百六十七
1200003456 十二亿零三千四百五十六
1200000345 十二亿零三百四十五
1200000034 十二亿零三十四
1200000003 十二亿零三
1230000000 十二亿三千万
1234000000 十二亿三千四百万
1234500000 十二亿三千四百五十万
1234560000 十二亿三千四百五十六万
1234567000 十二亿三千四百五十六万七千
1234567800 十二亿三千四百五十六万七千八百
1234567890 十二亿三千四百五十六万七千八百九十
2147483647 二十一亿四千七百四十八万三千六百四十七
9223372036854 九万二千二百三十三亿七千二百零三万六千八百五十四
9002233007200 九万零二十二亿三千三百万七千二百


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章