Java 将浮点数转换成人民币读法字符串

《疯狂Java讲义(第4版)》第4章 流程控制与数组 本章练习 5

编写一个程序,将浮点数转换成人民币读法字符串,例如,将1006.333转换成壹千零陆元叁角叁分。

        参考已有的解决方案上进一步完善,在1000亿范围内基本符合人民币金额读写规范。

特殊情况解决:

  • 输入的数为0直接输出“零元整”
  • 小数位只有分位且整数位不为零时分位前应加“零”,例如,12.04应转换成“壹拾贰元肆分”
  • 小数位为零且整数位不为零时应在整数位后加“整”,例如,12应转换成“壹拾贰元整”
  • 分组转换时,如果分成3组,若中间一组全是零,会只保留一个零,又因为最低位为零而被删除,进而这一组返回值为空,但这里又需要一个零,例如,100001234应转换成“壹亿壹仟贰佰叁拾肆元整”,而不是“壹亿壹仟贰佰叁拾肆元整”
  • 解决上一个问题后,1亿的转换结果会多一个零:壹亿元整。设置条件如果中间一组全是零且上一组也全是零,删除这个零
  • 解决上两个问题后,100000001(一亿零一):第一组“0001”会保留一个零,而第二组“0000”不满足上一个特殊情况的条件,依然会保留一个零,就会转换成“壹亿零零壹佰元整”,删除多余的零
public class Num2Rmb {
    private final String[] hanArr = {"零" , "壹" , "贰" , "叁" , "肆" ,
            "伍" , "陆" , "柒" , "捌" , "玖"};
    private final String[] unitArr = {"拾" , "佰" , "仟"};
    private final String[] uArr = {"元" , "万" , "亿"};
    // 把浮点数分解成整数部分字符串
    private String divideZheng(double num) {
        long zheng = (long) num;
        return zheng + "";
    }
    // 把浮点数分解成小数部分字符串
    private String divideXiao(double num) {
        long xiao = Math.round((num - (long) num) * 100);
        return String.valueOf(xiao);
    }
    // 把一个小于等于四位的数字字符串变成汉字字符串
    private String zhengToStr(String numStr) {
        int numLength = numStr.length();    // 字符串长度
        int resultLength = 0;               // 转换结果长度
        String result = "";
        // 依次遍历数字字符串的每一位数字
        for (int i = 0; i < numLength; i++) {
            // 将char型数字转换成int型数字
            int num = numStr.charAt(i) - 48;
            // 如果不是最后一位数字,且数字不是零,则需添加单位(拾,佰,仟)
            if (i != (numLength - 1) && num != 0)
                result += hanArr[num] + unitArr[numLength - 2 - i];
            // 如果第一位为零,直接转换
            else if (i == 0 && num == 0)
                result += hanArr[num];
            // 如果多个零连在一起,只保留一个零
            else if (!(num == 0 && result.charAt(resultLength - 1) == '零'))
                result += hanArr[num];
            // 长度随着转换进度而变化
            resultLength = result.length();
        }
        // 最低位是零,删除最低位
        if (result.charAt(resultLength - 1) == '零') {
            result = result.substring(0, resultLength - 1);
        }
        return result;
    }
    // 把小数部分数字字符串变成汉字字符串
    private String xiaoToStr(String numStr) {
        // 小数部分有两位
        if (numStr.length() == 2) {
            int jiao = numStr.charAt(0) - 48;
            int fen = numStr.charAt(1) - 48;
            if (fen != 0) return hanArr[jiao] + "角" + hanArr[fen] + "分";
            // 小数第二位(分)为0
            else return hanArr[jiao] + "角";
        }
        // 小数部分只有一位且不为零
        else if (numStr.length() == 1 && !numStr.equals("0")) {
            int fen = Integer.parseInt(numStr);
            return hanArr[fen] + "分";
        }
        // 小数部分为零
        else return "整";
    }
    // 将整数部分字符串按四位为一组,分组转换成汉字字符串,不足四位的单独转换
    private String zhengDivide(String numStr) {
        int numLength = numStr.length(); // 整数位长度
        // 整数位过长
        if (numLength > 11) {
            return "too large";
        }
        // 整数位为零
        if (numLength == 1 && numStr.charAt(0) == '0')
            return "";
        // 分为几组
        int arr = (numLength - 1) / 4 + 1;

        String result = ""; // 存放转换结果
        String temp;   // 中间变量,临时存放
        String zheng;  // 存放要拿去转换的数字字符串
        // 满四位的有几组进行几次循环
        for (int i = 1; i < arr; i++) {
            numLength = numStr.length();
            zheng = numStr.substring(numLength - 4);
            numStr = numStr.substring(0, numLength - 4);
            // 对特殊情况中间一组全是零,如100002894
            if (i != 1 && allZero(zheng)) {
                temp = "零" + result;
            }
            // 正常情况
            else {
                temp = zhengToStr(zheng);
                temp += uArr[i - 1] + result;
            }
            result = temp;
        }
        // 不足四位的单独转换
        temp = zhengToStr(numStr);
        temp += uArr[arr - 1] + result;
        result = temp;
        // 特殊情况1亿转换结果为“壹亿零元整”,删除“零”
        if (result.charAt(result.length() - 2) == '零') {
            result = result.substring(0, result.length() - 2) +
                    result.substring(result.length() - 1);
        }
        // 特殊情况万位和千位都为零会出现连续两个零
        // 如100000100的转换结果为“一亿零零壹佰元整”,删除多余的零
        for (int j = 0; j < result.length(); j++) {
            if (result.charAt(j) == '零' && result.charAt(j + 1) == '零') {
                result = result.substring(0, j) + result.substring(j + 1);
                break;
            }
        }

        return result;
    }
    // 判断zhengDivide方法中变量zheng是否全为零
    private boolean allZero(String zheng) {
        boolean a = true;
        for (int i = 0; i < 4; i++) {
            if (zheng.charAt(i) != '0') {
                a = false;
                break;
            }
        }
        return a;
    }

    public static void main(String[] args) {
        Num2Rmb nr = new Num2Rmb();
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            double num = sc.nextDouble();
            String zheng = nr.zhengDivide(nr.divideZheng(num));
            String xiao = nr.xiaoToStr(nr.divideXiao(num));
            // 判断输入的浮点数是否为零
            if (Math.round(num * 100) == 0)
                System.out.println("零元整");
            // 整数位过长
            else if (zheng.equals("too large"))
                System.out.println("金额过大,应小于1000亿元!");
            // 如果整数位不为零且小数位只有分,在整数位和小数位之间加“零”
            else if (!zheng.equals("") &&
                    xiao.length() == 2 && xiao.charAt(1) == '分')
                System.out.println(zheng + "零" + xiao);
            else
                System.out.println(zheng + xiao);
        }
    }
}

测试结果:

         出于一种执着,写出了我能想到的最完善的方案,但依然有待改进完善,欢迎批评指正,交流讨论,给出更好的方法

 参考文章:java人民币读法转换_风叶翩翩的博客-CSDN博客

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
以下是一个可能的实现: ```python def number_to_chinese(num): # 数字到中文的映射 chinese_num = { 0: '零', 1: '壹', 2: '贰', 3: '叁', 4: '肆', 5: '伍', 6: '陆', 7: '柒', 8: '捌', 9: '玖' } # 单位到中文的映射 chinese_unit = { 0: '', 1: '拾', 2: '佰', 3: '仟', 4: '万', 8: '亿' } # 将点数整数和小数两部分 integer_part, decimal_part = str(num).split('.') integer_part = int(integer_part) # 将整数部分转换中文 integer_str = str(integer_part) integer_len = len(integer_str) chinese_str = '' zero_flag = False # 是否需要在连续的零后面添加一个零 for i, digit in enumerate(integer_str): # 处理整数位上的数字 chinese_str += chinese_num[int(digit)] # 添加数字对应的单位 if (integer_len - i - 1) in chinese_unit: chinese_str += chinese_unit[integer_len - i - 1] # 添加万和亿的单位 if (integer_len - i - 1) % 4 == 0: chinese_str += chinese_unit[integer_len - i - 1] # 处理连续的零 if digit == '0': zero_flag = True else: if zero_flag: chinese_str += chinese_num[0] zero_flag = False # 处理小数部分 if decimal_part: chinese_str += '点' for digit in decimal_part: chinese_str += chinese_num[int(digit)] return chinese_str + '元' def currency_to_chinese(num): # 将点数转换字符串形式 num_str = '%.2f' % num # 处理负数 if num_str[0] == '-': return '负' + currency_to_chinese(abs(num)) # 处理整数和小数部分 integer_part, decimal_part = num_str.split('.') # 处理整数部分 chinese_str = number_to_chinese(integer_part) # 处理小数部分 if decimal_part == '00': chinese_str += '整' else: chinese_str += number_to_chinese(decimal_part) + '分' return chinese_str print(currency_to_chinese(123456789.99)) # 壹亿贰仟叁佰肆拾伍万陆仟柒佰捌拾玖元玖角玖分 print(currency_to_chinese(-123.45)) # 负壹佰贰拾叁元肆角伍分 ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

会议开始

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值