JAVA浮点数浮点数转换成人民币读法

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhaohuiyang_949/article/details/80204415

    侵删!

    在《疯狂JAVA讲义》第4章最后练习题中,第5题:编写一个程序,将浮点数转换成人民币读法字符串,例如,将1006.33转换成一千零六元三角三分。

    这个题主要是一个逻辑判断的过程。首先考虑的问题是整数部分和小数部分,我们在这里给小数部分做个限制,因为只有角和分,所以就固定判断小数部分只有两位数。小数部分就分别判断角和分。接下来是整数部分,由于考虑到整数部分可能过长,所以我们在处理的时候,将整数部分分割成4个数为一部分,一部分一部分的来处理。每一个部分都是4位数,就分别判断千,百,十。在判断的过程中,要注意“零”问题的处理,比如:1003。这个是我参考的原文章:java实战1——浮点数转人民币读法

    以下是完整的代码,代码中有详细的注释:

import java.util.Scanner;

public class FloatToChinese {

    //汉字数组
    private String[] chineseArr = new String[]{"零","一","二","三","四","五","六","七","八","九"};
    //单位数组
    private String[] unitArr = new String[]{"千","百","十"};

    public static void main(String[] args) {
        // write your code here
        FloatToChinese floatToChinese = new FloatToChinese();
        Scanner console = new Scanner(System.in);
        //保存输入的数值
        double num = 0.0;
        num = console.nextDouble();
        String result = floatToChinese.numStrToChineseStr(num);
        System.out.println(result);
    }

    /**
     * 四位数的字符串转人民币读法
     * 如果输入numStr 不够4位就前补零,变为4位
     * @param numStr    将整个数字字符串分割成每4位数一组后的,数字字符串
     * @return  当前4位数字转换成人民币读法后的,汉字字符串
     */
    public String numStrToChineseStrIntPartCore(String numStr) {
        String result = "";             //保存结果,初始化为空
        int len = numStr.length();      //获取numStr的长度
        //补零操作
        if(len < 4) //位数小于4位就在前面补零
        {
            String[] addZeroStr = {"0","00","000"};
            //4减去长度等于需要补零的个数,要补充的0在addZeroStr中,需要使用数组下标,所以再减一
            numStr = addZeroStr[4-len-1] + numStr;
        }
        len = numStr.length();      //更新长度,len==4
        //扫描至第一个不为0的字符
        int i=0;
        //i表示下标,下标小于长度,并且截取字符串的每一个字符和“0”比较
        while(i < len && numStr.charAt(i)-'0'==0){
            i++;
        }
        //如果4个数都是0,那么直接输出一个0,并返回结果。
        if(i==len){
            result += "零";
            return result;
        }
        //四个数不都为0的情况,扫描4个数
        for(;i < len; i++){
            //使用单引号时表示char,使用双引号时,表示String
            //charAt()返回的是一个char类型的值,char类型的值,可以直接相减(自动转换成ASCLL码值相减)
            //获取的单个字符,和0的ASCLL码值相差多少,数值就是多少。
            int num = numStr.charAt(i) - '0';
            //不是末尾且不为0
            if( i != len-1 && num != 0){
                //直接映射汉字和单位,num汉字的下标,i单位的下标
                result += chineseArr[num] + unitArr[i] ;
            } else {
                //若当前结果字符串中最后一位不是“零”,且数字串最后一位不是数字0 这样对中间2个零的只添加一个“零”如1003
                if( result.length()>0 && result.charAt(result.length()-1) != '零'
                        && numStr.charAt(len-1)-'0'!= 0) {
                    //四位中第二,三位至少有一个为0且最后一位数字不为0 如1003 则为一千零三
                    if((i==1||i==2) && num == 0){
                        result += "零";
                    }
                }
                //是最后一位,且数字不为0 不加单位
                if( i == len - 1 && num != 0) {
                    result += chineseArr[num];
                }
            }
        }
        return  result; //返回结果字符串
    }

    /**
     * 获取数字字符串有效位
     * 从第一位开始,不为0的数
     * @param str   整个数字字符串
     * @return  返回第一个不为0的数字的位置
     */
    public int getValidStrLen(String str) {
        //起始位置
        int start = 0;
        //当前数字字符串长度
        int len = str.length();
        //从第一个开始遍历,如果为0,就检查下一个,不为0就找到第一个有效数字
        while(start < len  && str.charAt(start) =='0'){
            start++ ;
        }
        //start++,表示了当前无效位的个数,计算的时候分成4个数字一组
        return 4 - start;
    }

    /**
     * 将12位整数部分数字转为汉字字符串
     * @param numStr    整个数字字符串
     * @return  整个数字字符串转换为人民币读法后的汉字字符串
     */
    public String numStrToChineseStrIntPart(String numStr) {
        //获取整个数字字符串的总长度
        int len = numStr.length();
        //判断输入的数字字符串分成4位1组,能分成几份
        int partNum = (len%4==0) ? (len/4) : (len/4)+1;
        //分别定义亿,万,元单位字符串
        String strYi="",strWan="",strYuan="";
        //12位以内的数字字符串最多能分成三部分
        String firstStr,secondStr,thirdStr;
        //用于保存分割成4位后的数字字符串有效字符串长度,去除0
        int tempLen;
        boolean fourValidBitYuan = false ; //判断第三部分是否为4位
        switch(partNum) {
            //只有1部分,就是xxx元
            case 1:
                //如果只有1部分,就不用分割,直接转换
                strYuan += numStrToChineseStrIntPartCore(numStr);
                break;
            //有2部分,就是 xxx万xxx元
            case 2:
                //注意 String.substring(beginindex,endIndex)中endindex不包含
                int endIndex = len - 4 ;
                //一部分一部分的截取
                firstStr = numStr.substring(0,endIndex);
                strWan += numStrToChineseStrIntPartCore(firstStr)+"万";
                secondStr = numStr.substring(endIndex,len);
                strYuan += numStrToChineseStrIntPartCore(secondStr);
                tempLen = getValidStrLen(secondStr);
                if(0 <tempLen && tempLen < 4 ){
                    strYuan = "零"+ strYuan;
                }
                break;
            //有3部分,就是 xxx亿xxx万xxx元
            case 3:
                int endIndex2 = len - 4;
                int endIndex1 = endIndex2 - 4;
                firstStr = numStr.substring(0,endIndex1);
                strYi +=  numStrToChineseStrIntPartCore(firstStr)+"亿";
                secondStr = numStr.substring(endIndex1,endIndex2);
                strWan += numStrToChineseStrIntPartCore(secondStr)+"万";
                tempLen = getValidStrLen(secondStr);
                //中间过程进行补零
                if(0< tempLen && tempLen<4 ) {
                    strWan = "零"+strWan;
                }
                thirdStr = numStr.substring(endIndex2,len);
                strYuan += numStrToChineseStrIntPartCore(thirdStr) ;
                tempLen = getValidStrLen(thirdStr);
                if(0 <tempLen && tempLen < 4 ){
                    strYuan = "零"+ strYuan;
                } else {
                    if( tempLen == 4)
                        fourValidBitYuan  = true;
                }
                break;
                default:
                    break;
        }
        //对结果进行判断,如果万位和元位都为0
        if(strWan.equals("零万")) {
            //Str_wan为"零万"且元部分为4位。如12300001234中间需读出"零"
            if(fourValidBitYuan ){
                strWan = "零";
            }
            //否则就不添加
            else{
                strWan = "";
            }
        }
        if( strYuan.equals("零")){
            strYuan = "";
        }
        return strYi + strWan + strYuan + "元";
    }

    /**
     * 处理小数部分字符串,小数部分最多两位
     * @param floatStr  小数部分字符串
     * @return  返回小数部分转换成人民币读法的汉字字符串
     */
    public String numStrToChineseStrFloatPart(String floatStr) {
        String resultJiao = "",resultFen = "";
        //小数部分长度
        int len  = floatStr.length();
        //补零操作,位数小于两位,就在前面补0
        if(len < 2) {
            //和整数部分补位,同理
            String[] addZeroStr = {"0","00"};
            floatStr = addZeroStr[2-len-1] + floatStr;
        }
        //固定的两位,角和分
        for(int i=0 ; i < 2 ; ++i) {
            //获取当前的数值
            int num = floatStr.charAt(i) - '0';
            //当是小数部分第一位的时候
            if( i == 0) {
                //映射数值
                resultJiao += chineseArr[num] ;
                //如果不等于0,添加单位
                if( num != 0){
                    resultJiao += "角";
                }
            }
            //当是小数部分第二位的时候
            else {
                //判断不为0,映射数值,并添加单位
                if(num !=0){
                    resultFen += chineseArr[num]+"分";
                }
            }
        }
        //检查一次,当小数部分两个数都为0的时候
        if( resultFen.equals("") && (resultJiao.equals("零")||resultJiao.equals("零角"))){
            resultJiao = "";
        }
        return resultJiao + resultFen;
    }

    /**
     * 将一个有效位为15以内的浮点数转换成人民币读法
     * @param num   将要转换的浮点数
     * @return  返回转换成人民币读法后的汉字字符串
     */
    public String numStrToChineseStr(double num) {
        //将浮点数直接强转成长整型
        long intPart = (long)num;
        //因为强转的时候,会造成精度丢失,使用Math.round进行四舍五入
        //浮点数减去整数部分等于小数部分,再*100,就等到小数部分的两个数值
        long floatPart = Math.round((num - intPart)*100);
        //将intPart和floatPart前面加个空字符串,将long型转换成字符串
        return numStrToChineseStrIntPart("" + intPart) + numStrToChineseStrFloatPart(""+floatPart);
    }
}   

    运行效果如图:


    整个代码,最关键的就是处理整数部分的逻辑问题,只要把这个逻辑关系捋清楚了就行。如果发现有问题,请指出,谢谢。

猜你喜欢

转载自blog.csdn.net/zhaohuiyang_949/article/details/80204415