Java浮点数转化为人民币读法字符串

Java浮点数转化为人民币读法字符串

效果图(零的处理有点复杂)

效果是出来了,但是觉得代码好臃肿
在这里插入图片描述
在这里插入图片描述在这里插入图片描述

主要思路

整数部分比较难处理
1、把12位整数划分为3组一组4位数字
2、分别遍历这三组数字
3、每遍历一组计算一次有效位数
4、根据有效位数的不同来判别零的增减
每一组数字“0”的分布有16种情况:
0000
0001
0010
0011
0100
0101
0110
0111
1000
1001
1010
1011
1100
1101
1110
1111
通过有效位数分为4组,然后在进行判断

import java.awt.desktop.SystemSleepEvent;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Scanner;

public class Num2Rmb {
    private String[] hanArr = {"零","壹","贰","叁","肆","伍","陆","柒","捌","玖"};
    private String[] unitArr = {"十","百","千"};
    boolean flag3 =  true;
    /**
     * 把一个浮点数分解成整数部分和小数部分的字符串
     * @param num 需要被分解的浮点数
     * @return 分解出来的整数部分和小数部分。第一个数组元素是整数部分,第二个数组元素是小数部分
     */
    private String[] divide(double num){
        //将一个浮点数强制转化成long型,即可得到整数部分
        var zheng = (long)num;
        //将浮点数减去整数部分得到小数部分,小数部分乘100取整得到2位小数
        var xiao = Math.round((num - zheng)*100);
        //使用了两种方法将整数转化为字符串
        return new String[]{zheng+"",String.valueOf(xiao)};
    }
    /**
     * 将浮点数转化为人民币读法的字符串
     * @param haveDivedNum 已经由divide()函数分离得到的字符数组。第一个数组元素是整数部分,第二个数组元素是小数部分。
     * @return 将浮点数转化成人民币读法的字符串
     */
    private String toHanStr(String[] haveDivedNum){
        var result = "";
        var zhengDigit = haveDivedNum[0].length();

        if (zhengDigit < 5){ //如果整数位数小于5,直接遍历后4位
            //如果整数部分长度为1,并且字符串的值为0,则不输出”元“
            if (haveDivedNum[0].length() == 1 && haveDivedNum[0].charAt(0)-48 == 0){
                result = erLastFourNum(haveDivedNum[0]) + xiao2RMB(haveDivedNum[1]) ;
            }else {
                result = erLastFourNum(haveDivedNum[0]) + "元" +  xiao2RMB(haveDivedNum[1]) ;
            }
        }else if (zhengDigit < 9){//如果整数位数大于4小于9
            result = erMidForNum(haveDivedNum[0]) + erLastFourNum(haveDivedNum[0]) + "元" + xiao2RMB(haveDivedNum[1]);
        }else if (zhengDigit < 13 ){
            result = erFirstFourNum(haveDivedNum[0])+erMidForNum(haveDivedNum[0]) + erLastFourNum(haveDivedNum[0]) + "元" + xiao2RMB(haveDivedNum[1]);
        }else result = "暂时不支持12位数字!";
        return result;
    }
    /**
     * 将浮点数分离后的小数部分转化为人民币读法的字符串
     * @param numStr 浮点数分离后的小数部分
     * @return 浮点数分离后的小数部分转化为人民币读法的字符串
     */
    private String xiao2RMB(String numStr){

        if(numStr.charAt(0)-48 != 0){
            return hanArr[numStr.charAt(0)-48] + "角" + hanArr[numStr.charAt(1)-48] + "分";
        }else return "";

    }
    /**
     * 遍历整数部分的最后四位
     * @param numStr 浮点数分离后的整数部分
     * @return 整数部分最后四位的中文读法
     */
    private String erLastFourNum(String numStr) {
        var effectNum = 4;
        StringBuilder result = new StringBuilder();
        int digit = numStr.length();
        var notAdd0_digit = digit;
        var startIndex = digit - 4;
        if (startIndex < 0) {//如果小于0,说明输入浮点数的整数部分位数小于4位需要补0
            //补零操作,(4 - digit)为所需补零的个数
            StringBuilder numStrBuilder = new StringBuilder(numStr);
            for (var i = 0; i < 4 - digit; i++) {
                numStrBuilder.insert(0, "0");
            }
            numStr = numStrBuilder.toString();
            //更新startIndex和digit
            startIndex = 0;
            digit = numStr.length();
        }
        for (var i = startIndex; i < digit; i++) {//遍历最后四位
            //计算有效位数effectNum
            //将char型的数字转化为int型的数字,因为它们的ASCII码相差48所以减去48
            var num = numStr.charAt(i) - 48;
            if (num == 0) {
                effectNum -= 1;
            } else {//遇到num不为0则跳出循环,得到有效位数
                break;
            }
        }
//        System.out.println(effectNum);
        switch (effectNum) {
            case 0://全是0
                result.append("");//不输出
                break;
            case 1://个位不为0,中文读法为几万"零"几
                var num1 = numStr.charAt(digit - 1) - 48;
                if (notAdd0_digit < 5){//如果没有补零时的实际位数小于5,则前面需要加"零",否则不用加
                    result.append(hanArr[num1]);
                }else result.append("零").append(hanArr[num1]);
                break;
            case 2:
                for (var i = startIndex; i < digit; i++) {//遍历最后四位
                    var num2 = numStr.charAt(i) - 48;
                    if (i != digit - 1 && num2 != 0) {
                        if (num2 == 1){//如果十位为1那么“壹”不用读,壹十壹元读作十壹元
                            result.append(unitArr[digit - 2 - i]);
                        }else result.append(hanArr[num2]).append(unitArr[digit - 2 - i]);
                    } else if (i == digit - 1 && num2 != 0){//如果个位不为0则加上对应数值的汉字
                        result.append(hanArr[num2]);
                    }else if (i == digit - 1 && num2 == 0){//如果个位为0则不用加零
                        result.append("");
                    }
                }
                if (notAdd0_digit < 5){
                    result.append("");
                }else result.insert(0,"零");//实际位数大于5则需要在前面补0
                break;
            case 3:
                for (var i = startIndex; i < digit; i++) {
                    var num3 = numStr.charAt(i)-48;
                    if (i != digit - 1 && num3 != 0){//这里没有处理个位数
                        result.append(hanArr[num3]).append(unitArr[digit - 2 - i]);
                    }else if (i != digit - 1 && i != startIndex && num3 ==0){//如果中间有个0,第一个零不能算进去
                        if (numStr.charAt(digit-1)-48==0) result.append("");
                        else result.append("零");
                    }else if (i == digit - 1 && num3 !=0){
                        result.append(hanArr[num3]);
                    }
                }
                if (notAdd0_digit < 5){
                    result.append("");
                }else {
                    result.insert(0,"零");
                }
                break;
            case 4:
                boolean flag = false;
                //先加单位
                for (var i = startIndex; i < digit; i++) {
                    var num4 = numStr.charAt(i)-48;
                    if (i != digit -1 && num4 != 0){
                        result.append(hanArr[num4]).append(unitArr[digit - 2 - i]);
                    }else if (i != digit -1 && num4 == 0 && (numStr.charAt(digit-1)-48 != 0|numStr.charAt(digit-2)-48!=0)){
                        if (flag == false){
                            result.append("零");
                            flag = true;
                        }else {
                            result.append("");
                        }
                    }else if (i == digit - 1 && num4 !=0){
                            result.append(hanArr[num4]);
                    }
                }
                break;
            }

        return result.toString();
    }
    /**
     * 将5~8位数字转化为中文读法
     * @param numStr 浮点数分离后的整数部分
     * @return 5~8位数字的中文读法
     */
    private String erMidForNum(String numStr){
        var flag1 = true;
        var effectNum = 4;
        StringBuilder result = new StringBuilder();
        int digit = numStr.length();
        var notAdd0_digit = digit;
        var startIndex = digit - 8;
        var endIndex = digit - 4 ;
        if (startIndex < 0) {//如果小于0,说明输入浮点数的整数部分位数小于4位需要补0
            //补零操作,(4 - digit)为所需补零的个数
            StringBuilder numStrBuilder = new StringBuilder(numStr);
            for (var i = 0; i < 8 - digit; i++) {
                numStrBuilder.insert(0, "0");
            }
            numStr = numStrBuilder.toString();
            //更新startIndex和digit
            startIndex = 0;
            digit = numStr.length();
            endIndex = digit - 4;
        }
        for (var i = startIndex; i <endIndex; i++) {//遍历最后四位
            //计算有效位数effectNum
            //将char型的数字转化为int型的数字,因为它们的ASCII码相差48所以减去48
            var num = numStr.charAt(i) - 48;
            if (num == 0) {
                effectNum -= 1;
            } else {//遇到num不为0则跳出循环,得到有效位数
                break;
            }

        }
        switch (effectNum) {
            case 0://全是0
                boolean flag4 = false;
                for (var i = digit - 4; i < digit; i++){
                    if (numStr.charAt(i)-48!=0){
                        flag4 = true;
                        break;
                    }
                }
                if (flag4){//为真说明最后4位都为0
                    result.append("零");
                }else {
                    result.append("");
                }
                flag1 =false;
                break;
            case 1://个位不为0,中文读法为几万"零"几
                var num1 = numStr.charAt(endIndex - 1) - 48;
                if (notAdd0_digit <= 5){//如果没有补零时的实际位数小于5,则前面需要加"零",否则不用加
                    result.append(hanArr[num1]);
                }else result.append("零").append(hanArr[num1]);
                break;
            case 2:
                for (var i = startIndex; i < endIndex; i++) {//遍历最后四位
                    var num2 = numStr.charAt(i) - 48;
                    if (i != endIndex - 1 && num2 != 0) {
                        if (num2 == 1 && notAdd0_digit == 6){//如果十位为1那么“壹”不用读,壹十壹元读作十壹元
                            result.append(unitArr[endIndex - 2 - i]);
                        }else result.append(hanArr[num2]).append(unitArr[endIndex - 2 - i]);
                    } else if (i == endIndex - 1 && num2 != 0){//如果个位不为0则加上对应数值的汉字
                        result.append(hanArr[num2]);
                    }else if (i == endIndex - 1 && num2 == 0){//如果个位为0则不用加零
                        result.append("");
                    }
                }
                if (notAdd0_digit < 8){
                    result.append("");
                }else result.insert(0,"零");//实际位数大于8则需要在前面补0
                break;
            case 3:
                for (var i = startIndex; i < endIndex; i++) {
                    var num3 = numStr.charAt(i)-48;
                    if (i != endIndex - 1 && num3 != 0){//这里没有处理个位数
                        result.append(hanArr[num3]).append(unitArr[endIndex - 2 - i]);
                    }else if (i != endIndex - 1 && i != startIndex && num3 ==0){//如果中间有个0,第一个零不能算进去
                        if (numStr.charAt(endIndex-1)-48==0) result.append("");
                        else result.append("零");
                    }else if (i == endIndex - 1 && num3 !=0){
                        result.append(hanArr[num3]);
                    }
                }
                if (notAdd0_digit < 8){
                    result.append("");
                }else {
                    result.insert(0,"零");
                }
                break;
            case 4:
                boolean flag = false;
                //先加单位
                for (var i = startIndex; i < endIndex; i++) {
                    var num4 = numStr.charAt(i)-48;
                    if (i != endIndex -1 && num4 != 0){
                        result.append(hanArr[num4]).append(unitArr[endIndex - 2 - i]);
                    }else if (i != endIndex -1 && num4 == 0 && (numStr.charAt(endIndex-1)-48 != 0|numStr.charAt(endIndex-2)-48!=0)){
                        if (flag == false){
                            result.append("零");
                            flag = true;
                        }else {
                            result.append("");
                        }
                    }else if (i == endIndex - 1 && num4 !=0){
                        result.append(hanArr[num4]);
                    }
                }
                break;
        }
        if(flag1){
            return result.append("万").toString();
        }else {
            return result.toString();
        }

    }
    /**
     * 将9~12位数字转化为中文读法
     * @param numStr 分离后的整数部分
     * @return 9~12位数字的中文读法
     */
    private String erFirstFourNum(String numStr){
        var effectNum = 4;
        StringBuilder result = new StringBuilder();
        int digit = numStr.length();
        var notAdd0_digit = digit;
        var startIndex = 8 - digit;
        var endIndex = digit - 8 ;
        if (startIndex < 0) {//如果小于0,说明输入浮点数的整数部分位数小于4位需要补0
            StringBuilder numStrBuilder = new StringBuilder(numStr);
            for (var i = 0; i < 12- digit; i++) {
                numStrBuilder.insert(0, "0");
            }
            numStr = numStrBuilder.toString();
            //更新startIndex和digit
            startIndex = 0;
            digit = numStr.length();
            endIndex = digit - 8;
        }
        for (var i = startIndex; i <endIndex; i++) {//遍历最后四位
            //计算有效位数effectNum
            //将char型的数字转化为int型的数字,因为它们的ASCII码相差48所以减去48
            var num = numStr.charAt(i) - 48;
            if (num == 0) {
                effectNum -= 1;
            } else {//遇到num不为0则跳出循环,得到有效位数
                break;
            }

        }
        switch (effectNum) {
            case 0://全是0
                result.append("");//
                break;
            case 1://个位不为0,中文读法为几万"零"几
                var num1 = numStr.charAt(endIndex - 1) - 48;
                result.append(hanArr[num1]);
                break;
            case 2:
                for (var i = startIndex; i < endIndex; i++) {//遍历最后四位
                    var num2 = numStr.charAt(i) - 48;
                    if (i != endIndex - 1 && num2 != 0) {
                        if (num2 == 1 && notAdd0_digit == 10){//如果十位为1那么“壹”不用读,壹十壹元读作十壹元
                            result.append(unitArr[endIndex - 2 - i]);
                        }else result.append(hanArr[num2]).append(unitArr[endIndex - 2 - i]);
                    } else if (i == endIndex - 1 && num2 != 0){//如果个位不为0则加上对应数值的汉字
                        result.append(hanArr[num2]);
                    }else if (i == endIndex - 1 && num2 == 0){//如果个位为0则不用加零
                        result.append("");
                    }
                }
                break;
            case 3:
                for (var i = startIndex; i < endIndex; i++) {
                    var num3 = numStr.charAt(i)-48;
                    if (i != endIndex - 1 && num3 != 0){//这里没有处理个位数
                        result.append(hanArr[num3]).append(unitArr[endIndex - 2 - i]);
                    }else if (i != endIndex - 1 && i != startIndex && num3 ==0){//如果中间有个0,第一个零不能算进去
                        if (numStr.charAt(endIndex-1)-48==0) result.append("");
                        else result.append("零");
                    }else if (i == endIndex - 1 && num3 !=0){
                        result.append(hanArr[num3]);
                    }
                }
                break;
            case 4:
                boolean flag = false;
                //先加单位
                for (var i = startIndex; i < endIndex; i++) {
                    var num4 = numStr.charAt(i)-48;
                    if (i != endIndex -1 && num4 != 0){
                        result.append(hanArr[num4]).append(unitArr[endIndex - 2 - i]);
                    }else if (i != endIndex -1 && num4 == 0 && (numStr.charAt(endIndex-1)-48 != 0|numStr.charAt(endIndex-2)-48!=0)){
                        if (flag == false){
                            result.append("零");
                            flag = true;
                        }else {
                            result.append("");
                        }
                    }else if (i == endIndex - 1 && num4 !=0){
                        result.append(hanArr[num4]);
                    }
                }
                break;
        }
        return result.append("亿").toString();
    }
    public static void main(String[] args) {
        var nr = new Num2Rmb();
        var line = "";
        Scanner scanner = new Scanner(System.in);
        while (true) {
            System.out.println("请输入一个浮点数:(输入“q”退出):");
            line = scanner.nextLine();
            if (line.equals("q")){
                break;
            }
            try {
                var d = Double.parseDouble(line);
                var result = nr.toHanStr(nr.divide(d));
                if (result.isEmpty()) {
                    System.out.println("请输入大于0的数");
                } else {
                    System.out.println("中文读法为:" + result);
                    System.out.println("-----------------------------------------------");
                }
            } catch (Exception e) {
                System.out.println("输入错误!");
                System.out.println("----------------------------");
            }
        }
    }
}

posted @ 2019-08-28 19:39  消灭猕猴桃  阅读(188)  评论(0编辑  收藏  举报