本人是從事互聯網金融行業的,所以會接觸到一些金融類的問題,常見的一種就是數字轉漢字大小寫的問題。所以抽空就寫了一個小小的工具類,實現了數字轉漢字、大數相加、相減、相乘的工具類,希望能幫助有需求的同行們。本篇就分享一下數字轉化為漢字的思路吧。
數字轉漢字的原理:
- 拆分:由于整數部分要加權值,而小數部分直接轉換即可,所以首先要將數字拆分成整數+小數;
- 整數處理:按照我們的中國人的習慣,把數字格式化成4位一組,不足4位前面補0。每次處理4位,按位匹配數組中的漢字+權值。即按照數值找數字數組(num_lower 、num_upper )中對應位置的漢字,按照在4位中的偏移量在單位權值數組(unit_lower 、unit_upper )中找。比如21,轉化4位為0021,前面的0不用管,2對應數字“二”,權值是“十”,1對應數字“一”,權值是“(個)”用空字符串代替。即得到“二十一”。每4位處理完后,還要整體對應一個權值,比如“萬、億、兆”等;
- 小數處理:小數部分直接按位對應漢字數組和權值即可。
廢話了這么多,可能云里霧里的,看看具體代碼吧:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
//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<String> 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<intnums.length;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(); } |
拆分整數和小數的方法在這里:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
|
/** * 獲取整數部分 * * @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 RuntimeException( "數字[" +num+ "]格式不正確!" ); } if (num.replaceAll( "[\\d|\\.|\\-|\\+]" , "" ).length()> 0 ){ throw new RuntimeException( "數字[" +num+ "]格式不正確!" ); } } |
通過這種分而治之的思路,處理起來就簡單多了。寫個main函數調用一下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
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” 轉換成“一億零一”而非“一億零萬零一”。
這里只分享了一個轉換漢字的功能,下篇將分享一下大數相乘、相加、相減的方法。支持小數和負數的運算,敬請期待。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。
原文鏈接:http://blog.csdn.net/xiaoxian8023/article/details/49834589