2019独角兽企业重金招聘Python工程师标准>>>
@author CeoiHong
答:首先分析数字的读法规则,将数字每四位一组,每组末尾连续的0读作 仟(如1000)、佰(100)、拾(10),非0数字之前的0读零,多个0只读一个零。
每四个数一组,组的单位从右往左依次是 : 一(不读)、萬、亿...这里不考虑更大的数。
当一组数全为0时,所处的位置不同,读法也不同。比如1010 0000 1010 中读零;1010 0000 0000 这里不读出来。
先确定每组数的读法,再确定该组的单位,最后将各组的读法连接起来即可。
每个四位数组先判断千位数是否为0,再判断百位数,再判断十位数,最后判断个位数。
这种四层嵌套判断比较麻烦,容易出错。所以在纸上画出判断的先后顺序会好理解点。
* 下面是判断的顺序:
* 仟 佰 拾 个
* 1 1 1 1 x仟x佰x拾x ---x代表阿拉伯数字的中国传统写法,如 1 对应 壹
* 1 1 1 0 x仟x佰x拾
*
* 1 1 0 1 x仟x佰零x
* 1 1 0 0 x仟x佰
*
* 1 0 1 1 x仟零x拾x
* 1 0 1 0 x仟零x拾
*
* 1 0 0 1 x仟零x
* 1 0 0 0 x仟
*
* 0 1 1 1 x佰x拾x
* 0 1 1 0 x佰x拾
*
* 0 1 0 1 x佰零x
* 0 1 0 0 x佰
*
* 0 0 1 1 x拾x
* 0 0 1 0 x拾
*
* 0 0 0 1 x
* 0 0 0 0 零/不读
* 每个四位数组都只有这16中情况,将每种可能的情况进行判断后即可得到正确的读法。
* 确定了单组的读法之后,组的排序不同又有不同的读法。针对不同单位内的读法,采取与上面相同的操作
* 全为0的记为0,非全0的记为1,即又有以下几种可能情况:
* 亿 萬 一
* 1 1 1 x亿x萬x ----x代表每4位数组的写法,如1034 对应 壹仟零叁拾肆
* 1 1 0 x亿x萬
* 1 0 1 x亿零x ---如果最后一组数是0开头,则删除一个“零”
* 1 0 0 x亿
* 1 1 x萬x
* 1 0 x萬
* 1 x
public static void main(String[] args) {//关联输入流,读取键盘录入。Scanner sc = new Scanner(System.in);System.out.println("输入一个12位以内的数字,输入end结束:");//循环录入数据while(true){String input = sc.next();//如果输入数据是0开头,去掉数据头部的0String num = null;for(int i=0;i<input.length();i++){if(input.charAt(i) != '0'){num = input.substring(i);break;}}//输入数字长度超过12则跳过此次循环if(num.length() > 12){System.out.println("请输入12位以内的数字:");continue;}//输入end结束录入if(num.equals("end"))break;//解析该数字writeWithUnit(num);}}private static void writeWithUnit(String num) {//四位数一组,不足四位的也作为一组。int groups = (int) Math.ceil(num.length()/4.0);//创建一个和组数相同的字符串数组。String[] parts = new String[groups];//不足四位的第一组内数字个数,比如“123456”,第一组内存放“12”,第二组存放“3456”int firstGroup = num.length()%4;if(firstGroup != 0){for(int i=0;i<groups;i++){if(i==0){parts[i] = num.substring(0, firstGroup);}else{parts[i] = num.substring((i-1)*4 + firstGroup,i*4 + firstGroup);}}}else{//如果数字刚好可以被4整除,则每组放4个数字for(int i=0;i<groups;i++){parts[i] = num.substring(i*4,(i+1)*4);}}StringBuffer sb = new StringBuffer();/*** 由于全0组的位置会影响单位和写法,所以采用和writeInTraditionalWay方法中相同的判断方法* 每组数中,四位全0的记为0,非全0 的记为1,在考虑的范围内(不考虑亿以上级别的数)的可能情况有下面几种。* 1 1 1* 1 1 0* 1 0 1* 1 0 0* 1 1* 1 0* 1* 依次对数字个数的不同进行判断。*///只有一组数时,即只有1~4位数if(groups == 1){sb.append(writeInTraditionalWay(parts[0]));//不满4位的在writeInTraditionalWay方法中在StringiBuffer对象首部添加了“零”,这里去掉首部的“零”。if(parts[0].length()<4){sb.deleteCharAt(0);}//当有两组数时,即有5~8位数}else if(groups == 2){sb.append(writeInTraditionalWay(parts[0])).append("萬");//在不足8位数时,即第一组数不足4位,在StringBuffer对象首部添加了“零”,要去掉首部的“零”。if(parts[0].length()<4){sb.deleteCharAt(0);}//第二组数如果不是全0,则添加到sb末尾,单位“一”省略不写。if(!parts[1].contains("0000"))sb.append(writeInTraditionalWay(parts[1]));//当有三组数时,即9~12位数}else if(groups == 3){sb.append(writeInTraditionalWay(parts[0])).append("亿");//在不足12位数时,即第一组数不足4位,在StringBuffer对象首部添加了“零”,要去掉首部的“零”。if(parts[0].length()<4){sb.deleteCharAt(0);}//如果第二组数不是全0,则添加到sb末尾,单位为“萬”if(!parts[1].contains("0000")){sb.append(writeInTraditionalWay(parts[1])).append("萬");//如果第三组数不全为0,则添加到sb末尾,单位为“一”,省略不写。if(!parts[2].contains("0000")){sb.append(writeInTraditionalWay(parts[2]));}//如果第二组数全为0}else{//如果第三组数不全为0则添加到sb末尾,单位为“一”,省略不写。如果全为0时,不读。比如1234 0000 5678中的四个0不读出来。if(!parts[2].contains("0000")){if(writeInTraditionalWay(parts[2]).startsWith("零")){sb.append(writeInTraditionalWay(parts[2]));}sb.append(writeInTraditionalWay(parts[1])).append(writeInTraditionalWay(parts[2]));}}}//输出System.out.println(sb.toString());}//将一个单独的四位数组转换成传统写法public static String writeInTraditionalWay(String str){StringBuffer sb = new StringBuffer();int i = Integer.parseInt(str);//得到这个数的千位,百位,十位,个位的数int qianwei = i/1000;i = i%1000;int baiwei = i/100;i = i%100;int shiwei = i/10;i = i%10;int gewei = i;//千位不为0if(qianwei > 0){//写作x仟sb.append(baseNumber(qianwei)).append("仟");//百位也不为0if(baiwei > 0){//写作x仟x佰sb.append(baseNumber(baiwei)).append("佰");//十位不为0if(shiwei > 0){//写作x仟x佰x拾sb.append(baseNumber(shiwei)).append("拾");//个位不为0if(gewei > 0){//写作x仟x佰x拾x,此时写法已经确定,返回该值。return sb.append(baseNumber(gewei)).toString();}else{//个位为0,写作x仟x佰x拾,写法确定,返回。return sb.toString();}//十位为0}else{if(gewei > 0){//个位不为0,写作x仟零x,写法确定,返回。return sb.append(baseNumber(0)).append(baseNumber(gewei)).toString();}else{//个位为0,写作,x仟x佰,写法确定,返回。return sb.toString();}}}else{//baiwei == 0 一下的判断和上面的判断类似。if(shiwei > 0){sb.append(baseNumber(0)).append(baseNumber(shiwei)).append("拾");if(gewei > 0){return sb.append(baseNumber(gewei)).toString();}else{return sb.toString();}}else{if(gewei > 0){return sb.append(baseNumber(0)).append(baseNumber(gewei)).toString();}else{return sb.toString();}}}}else{if(baiwei > 0){sb.append(baseNumber(0)).append(baseNumber(baiwei)).append("佰");if(shiwei > 0){sb.append(baseNumber(shiwei)).append("拾");if(gewei > 0){return sb.append(baseNumber(gewei)).toString();}else{return sb.toString();}}else{if(gewei > 0){return sb.append(baseNumber(0)).append(baseNumber(gewei)).toString();}else{return sb.toString();}}}else{if(shiwei > 0){sb.append(baseNumber(0)).append(baseNumber(shiwei)).append("拾");if(gewei > 0){return sb.append(baseNumber(gewei)).toString();}else{return sb.toString();}}else{if(gewei > 0){return sb.append(baseNumber(0)).append(baseNumber(gewei)).toString();}else{return sb.append(baseNumber(0)).toString();}}}}}//返回基本数字的写法public static String baseNumber(int i){switch(i){case 0:return "零";case 1:return "壹";case 2:return "贰";case 3:return "叁";case 4:return "肆";case 5:return "伍";case 6:return "陆";case 7:return "柒";case 8:return "捌";case 9:return "玖";default:return null;}}