Java疯狂讲义第四章数字转换人民币大写字符串

import java.util.*;
/**
*    @author: 小杜
*    time: 2020年4月17日17:58:09
*    
*/
public class NumToRmb{
    private String[] hanArr = {"零","壹","贰","叁","肆","伍","陆","柒","捌","玖"};
    private String[] unitArr = {"十","百","千","万"};
    private String[] allUnitArr = {"十","百","千","万","亿"};
    public static void main(String args[]){
        NumToRmb nr = new NumToRmb();
        //测试把一个浮点数分解成整数部分和小数部分
        System.out.println(Arrays.toString(new String[]{"1","a"}));
        System.out.println(Arrays.toString(nr.divide(236711125.123)));
        //测试把一个四位数的数字字符串变成汉子字符串
        System.out.println(nr.toHanStr("16109"));
        System.out.println(nr.toHanStr("13257"));


        //测试优化的方法
        //1、测试普通的12位以内的数字
        String[] numStr = nr.divide(2312_3671_1125.123); 
        System.out.println(nr.toHanStr(numStr));
        //2、测试大于非法数字转换(大于12位);
        try{
            String[] numStr2 = nr.divide(12_2312_3671_1125.123); 
            System.out.println(nr.toHanStr(numStr2));    
        }catch(RuntimeException e){
            e.printStackTrace();
        }
        //3、测试连续0的数字转换
        String[] numStr3 = nr.divide(0300_3001_1120.123); 
        System.out.println(nr.toHanStr(numStr3));
        String[] numStr4 = nr.divide(0300_3000_0120.123); 
        System.out.println(nr.toHanStr(numStr4));
        String[] numStr5 = nr.divide(0300_3000_0121.123); 
        System.out.println(nr.toHanStr(numStr5));


    }
    /**
    *    把一个浮点数分成整数部分和小数部分
    *    @param num 需要被分解的浮点数
    *    @return 分解出来的整数和小数部分,第一个元素是整数部分,第二个元素是小数部分
    */
    private String[] divide(double num){
        long zheng = (long)num;
        long xiao = Math.round((num - zheng)*100);
        return new String[]{zheng+"",String.valueOf(xiao)};
    }
    /**
    *    把输入的四位数数字字符串转换成汉字字符串
    *    @param numStr 需要被转换的四位数数字字符串
    *     @return 转换后的汉字字符串
    */    
    private String toHanStr(String numStr){
        //返回结果
        String result = "";
        int numLen = numStr.length();
        //依次遍历得到每一个数字
        for(int i = 0; i < numLen; i ++){
            //数字的ASCII - 48得到数字本身
            int num = numStr.charAt(i) - 48;
            //数字不为0时,且不为最后一个数时,需要添加单位
            if(i!=(numLen -1) && num != 0){
                //数字的大小与汉字的下标索引相对应
                result += hanArr[num];
                //数字的单位,为当前数字的位数(4)与unitArr中的相应单位(千)的索引(2)相对应
                result += unitArr[numLen - i - 2];
            }else{
                result += hanArr[num];
            }
        }
        return result;
    }
    /**
    *    上面方法的问题:
    *        1.不能对上十万的数进行转换
    *        2.对零的处理不够完善  对应遇到多个连续的0该如何转换?如3004 以及最高位或最低位的零该如何转换
    *        3.字符串太长的时候没有用逗号进行分隔,让其可读性变差
    *    @param numStr 需要转换的字符串数字(数组),其中第一个元素为整数部分,第二个元素为小数部分
    *    @return 转换后的结果 大写的汉字表示,并且带有元角分等单位  如壹元贰角叁分
    *    
    *    为解决以上三个问题,方法设计思路如下:
    *    对于1.问题的解决方案
    *    a. 十位到千位的数字跟对应的单位:十百千  
    *    b. 万位到千万位的数字跟对应的单位: 万十百千
    *    c. 亿位到千亿位的数字跟对应的单位: 亿十百千  
    *    d. 整数部分最大表示时 千亿  1000_1000_1000  长度12
    *    
    *    
    *        
    */
    private String toHanStr(String[] numStr) throws RuntimeException{
        String result = "";
        String zheng = numStr[0];
        String xiao = numStr[1];
        
        //对整数的处理
            
        int zhengLen = zheng.length();
        if(zhengLen > 12){
            throw new RuntimeException("整数部分大于12位数字,程序暂不支持此转换");
        }
        
        int countZero = 0;//记录连续0的个数;
        //12个位置对应的单位如下(j)
        //    1    2(十)       3(百)    4(千)
        //    5(万)    6       7        8
        //    9(亿)    10       11        12
        //    
        for(int i = 0; i < zhengLen; i ++){
            //当前数字
            int num = zheng.charAt(i) - 48;
            //它的位置 1-12 (对应上面)
            int j = zhengLen - i;
            //m 为1,2,3时后面跟对应的十百千的单位,反之(为0时)跟万亿或者不跟单位
            int m = (j - 1) % 4;
            if(m!=0 && num != 0){
                countZero = 0;
                result += hanArr[num];
                result += allUnitArr[m - 1];
                
            }else{
                //进入else的位置无非就是0或者单位为万或者亿的特殊位置
                if(num == 0)    
                    countZero ++;
                else
                    countZero = 0;//清零
                //0是第一个位置(个位)且是0  或 连续0的个数≥2时,不打印零
                //个位数不是0且连续0的个数<2时,打印
                if((j != 1 || num != 0) && countZero < 2){
                    result += hanArr[num];
                }
                //对于万位亿位为0 且
                if(countZero >= 2 && (j == 9 || j == 5)){
                    result = result.substring(0,result.length()-1);
                }
                if(j == 9){
                    result += allUnitArr[4];//"亿"
                    if(countZero >= 2)
                        result+="零";
                }
                if(j == 5){
                    result += allUnitArr[3];//"万"
                    if(countZero >= 2)
                        result+="零";
                }
            }
        }    
        
        result += "元,";
        
        //对小数的处理
        //02、20、22 分别为零贰分、贰角、贰角贰分;
        int jiao = xiao.charAt(0) - 48;    
        int fen = xiao.charAt(1) - 48;
        if(jiao != 0 && fen != 0){
            result += hanArr[jiao]+"角";
            result += hanArr[fen]+"分";
        }
        if(jiao == 0){
            result += hanArr[jiao];
            result += hanArr[fen]+"分";
        }
        if(fen == 0){
            result += hanArr[jiao]+"角";
        }
        return result;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值