Java常用数字工具类 数字转汉字(1)

网友投稿 473 2023-05-16


Java常用数字工具类 数字转汉字(1)

本人是从事互联网金融行业的,所以会接触到一些金融类的问题,常见的一种就是数字转汉字大小写的问题。所以抽空就写了一个小小的工具类,实现了数字转汉字、大数相加、相减、相乘的工具类,希望能帮助有需求的同行们。本篇就分享一下数字转化为汉字的思路吧。

数字转汉字的原理:

拆分:由于整数部分要加权值,而小数部分直接转换即可,所以首先要将数字拆分成整数+小数;

整数处理:按照我们的中国人的习惯,把数字格式化成4位一组,不足4位前面补0。每次处理4位,按位匹配数组中的汉字+权值。即按照数值找数字数组(num_lower 、num_upper )中对应位置的汉字,按照在4位中的偏移量在单位权值数组(unit_lower 、unit_upper )中找。比如21,转化4位为0021,前面的0不用管,2对应数字“二”,权值是“十”,1对应数字“一”,权值是“(个)”用空字符串代替。即得到“二十一”。每4位处理完后,还要整体对应一个权值,比如“万、亿、兆”等;

小数处理:小数部分直接按位对应汉字数组和权值即可。

废话了这么多,可能云里雾里的,看看具体代码吧:

//num 表示数字,lower表示小写,upper表示大写

private static final String[] num_lower = { "零", "一", "二", "三", "四", "五", "六", "七", "八", "九" };

private static final String[] num_upper = { "零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖" };

//unit 表示单位权值,lower表示小写,upper表示大写

private static final String[] unit_lower = { "", "十", "百", "千" };

private static final String[] unit_upper = { "", "拾", "佰", "仟"};

private static final String[] unit_common = {"","万", "亿","兆","京","垓","秭","穰","沟","涧","正","载"};

//允许的格式

private static final List promissTypes = Arrays.asList("INTEGER","INT","LONG","DECIMAL","FLOAT","DOUBLE","STRING","BYTE","TYPE","SHORT");

/**

* 数字转化为小写的汉字

*

* @param num 将要转化的数字

* @return

*/

public static String toChineseLower(Object num){

return format(num, num_lower, unit_lower);

}

/**

* 数字转化为大写的汉字

*

* @param num 将要转化的数字

* @return

*/

public static String toChineseUpper(Object num){

return format(num, num_upper, unit_upper);

}

/**

* 格式化数字

*

* @param num 原数字

* @param numArray 数字大小写数组

* @param unit 单位权值

* @return

*/

private static String format(Object num,String[] numArray,String[] unit){

if(!promissTypes.contains(num.getClass().getSimpleName().toUpperCase())){

throw new RuntimeException("不支持的格式类型");

}

//获取整数部分

String intnum = getInt(String.valueOf(num));

//获取小数部分

String decimal = getFraction(String.valueOf(num));

//格式化整数部分

String result = formatIntPart(intnum,numArray,unit);

if(!"".equals(decimal)){//小数部分不为空

//格式化小数

result += "点"+formatFractionalPart(decimal, numArray);

}

return result;

}

/**

* 格式化整数部分

*

* @param num 整数部分

* @param numArray 数字大小写数组

* @return

*/

private static String formatIntPart(String num,String[] numArray,String[] unit){

//按4位分割成不同的组(不足四位的前面补0)

Integer[] intnums = split2IntArray(num);

boolean zero = false;

StringBuffer sb = new StringBuffer();

for(int i=0;i

//格式化当前4位

String r = formatInt(intnums[i], numArray,unit);

if("".equals(r)){//

if((i+1)==intnums.length){

sb.append(numArray[0]);//结果中追加“零”

}else{

zero=true;

}

}else{//当前4位格式化结果不为空(即不为0)

if(zero || (i>0 && intnums[i]<1000)){//如果前4位为0,当前4位不为0

sb.append(numArray[0]);//结果中追加“零”

}

sb.append(r);

sb.append(unit_common[intnums.length-1-i]);//在结果中添加权值

zero=false;

}

}

return sb.toString();

}

/**

* 格式化小数部分

*

* @param decimal 小数部分

* @param numArray 数字大小写数组

* @return

*/

private static String formatFractionalPart(String decimal,String[] numArray) {

char[] val = String.valueOf(decimal).toCharArray();

int len = val.length;

StringBuilder sb = new StringBuilder();

for (int i = 0; i < len; i++) {

int n = Integer.valueOf(val[i] + "");

sb.append(numArray[n]);

}

return sb.toString();

}

拆分整数和小数的方法在这里:

/**

* 获取整数部分

*

* @param num

* @return

*/

private static String getInt(String num){

//检查格式

checkNum(num);

char[] val = String.valueOf(num).toCharArray();

StringBuffer sb = new StringBuffer();

int t , s = 0;

for (int i = 0; i < val.length; i++) {

if(val[i]=='.') {

break;

}

t = Integer.parseInt(val[i]+"",16);

if(s+t==0){

continue;

}

sb.append(t);

s+=t;

}

return (sb.length()==0? "0":sb.toString());

}

/**

* 获取小数部分

*

* @param num

* @return

*/

private static String getFraction(String num){

int i = num.lastIndexOf(".");

if(num.indexOf(".") != i){

throw new RuntimeException("数字格式不正确,最多只能有一位小数点!");

}

String fraction ="";

if(i>=0){

fraction = getInt(new StringBuffer(num).reverse().toString());

if(fraction.equals("0")){

return "";

}

}

return new StringBuffer(fraction).reverse().toString();

}

/**

* 检查数字格式

*

* @param num

*/

private static void checkNum(String num) {

if(num.indexOf(".") != num.lastIndexOf(".")){

throw new RuntimeException("数字["+num+"]格式不正确!");

}

if(num.indexOf("-") != num.lastIndexOf("-") || num.lastIndexOf("-")>0){

throw new RuntimeException("数字["+num+"]格式不正确!");

}

if(num.indexOf("+") != num.lastIndexOf("+")){

throw new RuntimeException("数字["+num+"]格式不正确!");

}

if(num.indexOf("+") != num.lastIndexOf("+")){

throw new Ruhttp://ntimeException("数字["+num+"]格式不正确!");

}

if(num.replaceAll("[\\d|\\.|\\-|\\+]", "").length()>0){

throw new RuntimeException("数字["+num+"]格式不正确!");

}

}

通过这种分而治之的思路,处理起来就简单多了。写个main函数调用一下:

public static void main(String[] args) {

short s = 10;

byte b=10;

char c='A';

Object[] nums = {s, b, c, 0, 1001, 100100001L, 21., 205.23F, 205.23D, "01000010", "1000000100105.0123", ".142", "20.00", "1..2", true};

System.out.println("将任意数字转化为汉字(包括整数、小数以及各种类型的数字)");

System.out.println("--------------------------------------------");

for(Object num :nums){

try{

System.out.print("["+num.getClass().getSimpleName()+"]"+num);

for(int i=0;i<25-String.valueOf(num+num.getClass().getSimpleName()).length();i+=4){

System.out.print("\t");

}

//调用转化为小写和大写

System.out.print(" format:"+toChineseLower(num));

System.out.println("【"+toChineseUpper(num)+"】");

}catch(Exception e){

System.out.println(" 错误信息:"+e.getMessage());

}

}

}

看看结果吧:

从上述代码和运行结果中,我们可以看到该功能支持多种数据类型的转换、支持转化为一般汉字和财务专用大写汉字。还可以智能处理非正常逻辑的数字。比如“20”会转化为“二十”而非“二十零”;“1 0000 0001” 转换成“一亿零一”而非“一亿零万零一”。

这里只分享了一个转换汉字的功能,下篇将分享一下大数相乘、相加、相减的方法。支持小数和负数的运算,敬请期待。

//格式化当前4位

String r = formatInt(intnums[i], numArray,unit);

if("".equals(r)){//

if((i+1)==intnums.length){

sb.append(numArray[0]);//结果中追加“零”

}else{

zero=true;

}

}else{//当前4位格式化结果不为空(即不为0)

if(zero || (i>0 && intnums[i]<1000)){//如果前4位为0,当前4位不为0

sb.append(numArray[0]);//结果中追加“零”

}

sb.append(r);

sb.append(unit_common[intnums.length-1-i]);//在结果中添加权值

zero=false;

}

}

return sb.toString();

}

/**

* 格式化小数部分

*

* @param decimal 小数部分

* @param numArray 数字大小写数组

* @return

*/

private static String formatFractionalPart(String decimal,String[] numArray) {

char[] val = String.valueOf(decimal).toCharArray();

int len = val.length;

StringBuilder sb = new StringBuilder();

for (int i = 0; i < len; i++) {

int n = Integer.valueOf(val[i] + "");

sb.append(numArray[n]);

}

return sb.toString();

}

拆分整数和小数的方法在这里:

/**

* 获取整数部分

*

* @param num

* @return

*/

private static String getInt(String num){

//检查格式

checkNum(num);

char[] val = String.valueOf(num).toCharArray();

StringBuffer sb = new StringBuffer();

int t , s = 0;

for (int i = 0; i < val.length; i++) {

if(val[i]=='.') {

break;

}

t = Integer.parseInt(val[i]+"",16);

if(s+t==0){

continue;

}

sb.append(t);

s+=t;

}

return (sb.length()==0? "0":sb.toString());

}

/**

* 获取小数部分

*

* @param num

* @return

*/

private static String getFraction(String num){

int i = num.lastIndexOf(".");

if(num.indexOf(".") != i){

throw new RuntimeException("数字格式不正确,最多只能有一位小数点!");

}

String fraction ="";

if(i>=0){

fraction = getInt(new StringBuffer(num).reverse().toString());

if(fraction.equals("0")){

return "";

}

}

return new StringBuffer(fraction).reverse().toString();

}

/**

* 检查数字格式

*

* @param num

*/

private static void checkNum(String num) {

if(num.indexOf(".") != num.lastIndexOf(".")){

throw new RuntimeException("数字["+num+"]格式不正确!");

}

if(num.indexOf("-") != num.lastIndexOf("-") || num.lastIndexOf("-")>0){

throw new RuntimeException("数字["+num+"]格式不正确!");

}

if(num.indexOf("+") != num.lastIndexOf("+")){

throw new RuntimeException("数字["+num+"]格式不正确!");

}

if(num.indexOf("+") != num.lastIndexOf("+")){

throw new Ruhttp://ntimeException("数字["+num+"]格式不正确!");

}

if(num.replaceAll("[\\d|\\.|\\-|\\+]", "").length()>0){

throw new RuntimeException("数字["+num+"]格式不正确!");

}

}

通过这种分而治之的思路,处理起来就简单多了。写个main函数调用一下:

public static void main(String[] args) {

short s = 10;

byte b=10;

char c='A';

Object[] nums = {s, b, c, 0, 1001, 100100001L, 21., 205.23F, 205.23D, "01000010", "1000000100105.0123", ".142", "20.00", "1..2", true};

System.out.println("将任意数字转化为汉字(包括整数、小数以及各种类型的数字)");

System.out.println("--------------------------------------------");

for(Object num :nums){

try{

System.out.print("["+num.getClass().getSimpleName()+"]"+num);

for(int i=0;i<25-String.valueOf(num+num.getClass().getSimpleName()).length();i+=4){

System.out.print("\t");

}

//调用转化为小写和大写

System.out.print(" format:"+toChineseLower(num));

System.out.println("【"+toChineseUpper(num)+"】");

}catch(Exception e){

System.out.println(" 错误信息:"+e.getMessage());

}

}

}

看看结果吧:

从上述代码和运行结果中,我们可以看到该功能支持多种数据类型的转换、支持转化为一般汉字和财务专用大写汉字。还可以智能处理非正常逻辑的数字。比如“20”会转化为“二十”而非“二十零”;“1 0000 0001” 转换成“一亿零一”而非“一亿零万零一”。

这里只分享了一个转换汉字的功能,下篇将分享一下大数相乘、相加、相减的方法。支持小数和负数的运算,敬请期待。


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Java中的FileInputStream 和 FileOutputStream 介绍_动力节点Java学院整理
下一篇:java实现字符串反转
相关文章

 发表评论

暂时没有评论,来抢沙发吧~