数字转中文字符串
考一下就知道从个位数开始每4位数的规则其实是一样的,大家用中文表示一下这串数字,是一千二百三十四
亿一千二百三十四
万一千二百三十四
,很明显以万、亿等单位区分的区间转换的规则是一样的,所以我们就可以先考虑0~9999这个区间的转换规则。
其次,对于其中一些特殊的大概的有这几种情况。
- 11,如果按照一个数字一个单位去放的话,这个数字会变成
一十一
,但是我们需要显示十一
,所以需要排除当十位数是一且只有两位数字的时候,去掉前面的一。 - 1001,中间有多个零,我们转换成中文数字的时候只需要一个汉字零,比如我们应该是
一千零一
,而不是一千零零一
,所以需要在循环中去除重复的零。 - 1000,还有这种情况去除重复的零后,会变成
一千零
,所以我们还得把最后一位是零且不只有零的这种情况的时候,去掉末尾的汉字零。
现在我们0~9999的数字大致已经构建完成了,然后将我们需要转换的数字从低位到高位4个分一组,然后将每组再用万、亿这些单位组和到一起,就可以构建出最后的答案啦!
public String num2Ch(long num) {
String[] convert = {"零", "一", "二", "三", "四", "五", "六", "七", "八", "九"};
String[] unit = {"个", "十", "百", "千", "万", "亿"};
if (num == 0) return convert[0];//0比较特殊
//将数字分为4个一组处理
Stack<String> stack = new Stack<>();
StringBuilder sb = new StringBuilder();
int pre = -1;//上一个数字
int count = 0;//记录当前处理了几个数字
while (num > 0) {
int digit = (int) (num % 10);
num = num / 10;
if (digit > 0 || (digit == 0 && pre != 0 && count > 0)) {//避免有多个零出现
//添加单位,首先要满足不是0
if (digit > 0 && count % 4 == 1) sb.append(unit[1]);
if (digit > 0 && count % 4 == 2) sb.append(unit[2]);
if (digit > 0 && count % 4 == 3) sb.append(unit[3]);
sb.append(convert[digit]);
}
pre = digit;
count++;
if (count == 4 || count == 8 || num <= 0) {//如果处理满一组或不满一组,但已经处理完
String s = sb.reverse().toString();
if (s.startsWith("一十")) s = s.substring(1);//特殊情况: 10 不念一十 ,念十
stack.push(s);
count = 0;//下一组重新初始化
pre = -1;
sb.setLength(0);
}
}
sb.setLength(0);//清空
//对栈中的数据进行处理
while (!stack.isEmpty()) {
sb.append(stack.pop());
if (stack.size() == 2) {//为亿
sb.append(unit[5]);
} else if (stack.size() == 1 && sb.charAt(sb.length() - 1) != '亿') {//为万,特殊情况 一亿,后面不能加万了
sb.append(unit[4]);
}
}
return sb.toString();
}
@Test
public void test() throws Exception {
//阿拉伯数字转中文数字
System.out.println(num2Ch(1));
System.out.println(num2Ch(10));
System.out.println(num2Ch(15));
System.out.println(num2Ch(25));
System.out.println(num2Ch(100));
System.out.println(num2Ch(115));
System.out.println(num2Ch(234));
System.out.println(num2Ch(999));
System.out.println(num2Ch(1501));
System.out.println(num2Ch(1006));
System.out.println(num2Ch(9905));
System.out.println(num2Ch(20394));
System.out.println(num2Ch(100001));
System.out.println(num2Ch(100000));
System.out.println(num2Ch(100101822));
System.out.println(num2Ch(123412341234L));
System.out.println(num2Ch(10000000000L));
}