华为OD机试B卷人民币转换Python解法详解(附完整解题思路及满分攻略)

文章目录

  • 题目描述
  • 阿拉伯数字金额转中文大写金额详解
  • 核心解题思路
  • 处理流程
  • 完整代码实现
  • 算法原理解析
  • 1. 整数部分处理
  • 2. 零处理规则
  • 3. 单位缩写规则
  • 4. 小数部分处理
  • 5. "整"字规则
  • 示例解析
  • 示例1:532.00
  • 示例2:6007.14
  • 示例3:99999.99
  • 总结
  • 题目描述

    将阿拉伯数字金额转换为中文大写金额格式,需遵循以下规则:
    1、 前缀要求:
    中文大写金额前必须标明“人民币”字样。
    2、用字规范:
    使用壹、贰、叁、肆、伍、陆、柒、捌、玖、拾、佰、仟、万、亿、元、角、分、零、整等字样。
    3、“整”字规则:
    金额到“元”为止时,在“元”后写“整”字(如532.00 一“人民币伍佰叁拾贰元整”)。
    金额含“角”或“分”时,不写“整”字(如6007.14 →“人民币陆仟零柒元壹角肆分”)。
    4、零的规则:
    阿拉伯数字中间有“0”时,中文大写写“零”(如1010.00 →“人民币壹仟零拾元整”)。
    连续多个“0”时,只写一个“零”(如6007.14 -“人民币陆仟零柒元壹角肆分”)。
    5、单位缩写规则:
    10写作“拾”,100写作“壹佰”(如110.00 →“人民币壹佰拾元整”)。
    十万以上数字接“仟”时不加“零”(如30105000.00 一“人民币叁仟零拾万伍仟元整”)。
    输入描述:
    输入一个double类型数字,表示待转换的金额(0≤输入≤1,000,000,000,000)。
    输出描述:
    输出符合规则的中文大写金额字符串

    示例1:
    输入:

    532.00

    输出:

    人民币伍佰叁拾贰元整

    说明:

    532的整数部分转换为“伍佰叁拾贰元”,小数部分是零,所以加上“整”字。

    示例2:
    输入:

    6007.14

    输出:

    人民币陆仟零柒元壹角肆分

    示例3:
    输入:

    99999.99

    输出:

    人民币玖万玖仟玖佰玖拾玖元玖角玖分

    阿拉伯数字金额转中文大写金额详解

    核心解题思路

    将阿拉伯数字金额转换为中文大写金额是金融系统中的常见需求。解题的核心在于分治处理:将数字分解为整数部分和小数部分,分别处理后再组合。关键点包括:

    1. 分层处理:整数部分按"亿、万、元"三级单位处理
    2. 小数处理:角、分单位处理,注意"整"字规则
    3. 零处理:连续零只写一个"零",末尾零省略
    4. 单位转换:亿(108)、万(104)、元(100)、角(10-1)、分(10^-2)

    处理流程

    1. 分离整数和小数部分
    2. 处理整数部分(核心):
    3. 按每4位分组(亿级、万级、元级)
    4. 每组内按千、百、十、个位处理
    5. 处理零的规则和单位缩写
    6. 处理小数部分:
    7. 角(第一位小数)
    8. 分(第二位小数)
    9. 组合结果,添加"人民币"前缀

    完整代码实现

    def to_rmb(amount):
        # 定义数字映射
        digits = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖']
        units = ['', '拾', '佰', '仟']
        levels = ['元', '万', '亿']
        
        # 分离整数和小数部分
        integer_part = int(amount)
        fractional_part = round(amount - integer_part, 2)
        
        # 处理整数部分
        def process_integer(num):
            if num == 0:
                return ['零']
                
            result = []
            level_idx = 0
            
            while num > 0:
                group = num % 10000  # 获取最后4位
                num //= 10000  # 移除已处理部分
                
                if group > 0:
                    group_str = []
                    zero_flag = False  # 是否已添加'零'
                    has_digit = False  # 当前组是否有非零数字
                    
                    # 处理千、百、十、个位
                    for i in range(3, -1, -1):
                        divisor = 10 ** i
                        digit = group // divisor
                        group %= divisor
                        
                        if digit > 0:
                            # 处理单位缩写规则(10写作"拾")
                            if i == 1 and digit == 1 and not has_digit:
                                group_str.append(units[i])  # "拾"不加"壹"
                            else:
                                group_str.append(digits[digit] + units[i])
                            zero_flag = False
                            has_digit = True
                        elif has_digit and not zero_flag and i > 0:  # 避免连续零
                            group_str.append('零')
                            zero_flag = True
                    
                    # 添加亿/万/元级单位
                    if level_idx > 0:
                        group_str.append(levels[level_idx])
                    result = group_str + result
                elif result and result[0] != '零':  # 处理组间零
                    result = ['零'] + result
                    
                level_idx += 1
            
            return result
        
        # 处理小数部分
        def process_fractional(frac):
            result = []
            # 角处理(0.1元 = 1角)
            jiao = int(frac * 10) 
            if jiao > 0:
                result.append(digits[jiao] + '角')
            
            # 分处理(0.01元 = 1分)
            fen = int(frac * 100) % 10
            if fen > 0:
                result.append(digits[fen] + '分')
            
            return result
        
        # 组合结果
        integer_str = process_integer(integer_part)
        fractional_str = process_fractional(fractional_part)
        
        # 添加"整"字规则
        if not fractional_str:
            integer_str.append('整')
        
        result = ['人民币'] + integer_str + fractional_str
        
        # 特殊情况处理(0元)
        if result == ['人民币', '零', '整']:
            return '人民币零元整'
            
        return ''.join(result)
    
    # 主程序
    try:
        amount = float(input().strip())
        print(to_rmb(amount))
    except:
        print("输入格式错误")
    

    算法原理解析

    1. 整数部分处理

    采用分组处理法,每4位一组(对应万、亿单位):

    while num > 0:
        group = num % 10000  # 取最后4位
        num //= 10000  # 移除已处理部分
        # 处理当前组...
    

    每组内部处理千、百、十、个位:

    for i in range(3, -1, -1):  # i=3(千位),2(百位),1(十位),0(个位)
        divisor = 10 ** i
        digit = group // divisor
        group %= divisor
        # 数字和单位映射...
    

    2. 零处理规则

    使用zero_flag标记处理连续零:

    if digit > 0:
        # 添加数字和单位
        zero_flag = False  # 重置零标记
    elif has_digit and not zero_flag:  # 非开头零且未标记
        group_str.append('零')
        zero_flag = True  # 标记已添加零
    

    3. 单位缩写规则

    特殊处理十位上的"1":

    if i == 1 and digit == 1 and not has_digit:
        group_str.append(units[i])  # 只添加"拾"
    else:
        group_str.append(digits[digit] + units[i])
    

    4. 小数部分处理

    jiao = int(frac * 10)  # 角(第一位小数)
    fen = int(frac * 100) % 10  # 分(第二位小数)
    

    5. "整"字规则

    if not fractional_str:  # 没有小数部分
        integer_str.append('整')
    

    示例解析

    示例1:532.00

  • 整数部分:532
  • 分组:0532 → 0(千),5(百),3(拾),2(个)
  • 处理:伍佰叁拾贰元
  • 小数部分:0.00 → 无角分
  • 结果:人民币伍佰叁拾贰元整
  • 示例2:6007.14

  • 整数部分:6007
  • 分组:6007 → 6(千),0(百),0(拾),7(个)
  • 零规则:6(仟)后直接7(元) → 添加"零"
  • 处理:陆仟零柒元
  • 小数部分:0.14
  • 角:1 → 壹角
  • 分:4 → 肆分
  • 结果:人民币陆仟零柒元壹角肆分
  • 示例3:99999.99

  • 整数部分:99999 → 9(万),9999(元)
  • 万级:9(万) → 玖万
  • 元级:9999 → 9(仟),9(佰),9(拾),9(个) → 玖仟玖佰玖拾玖元
  • 小数部分:0.99
  • 角:9 → 玖角
  • 分:9 → 玖分
  • 结果:人民币玖万玖仟玖佰玖拾玖元玖角玖分
  • 总结

    阿拉伯数字转中文大写金额的核心在于分层处理规则实现。关键点包括:

    1. 数据结构:使用映射表实现数字到中文的转换
    2. 分组策略:每4位一组处理亿、万、元级单位
    3. 零处理:通过状态标记避免连续零
    4. 特殊规则
    5. 十位上的"1"省略"壹"
    6. 末尾零省略
    7. 小数部分无时分写"整"

    实现时注意:

  • 边界条件处理(如0元、纯小数)
  • 浮点数精度问题(使用round处理)
  • 特殊规则优先级(零规则 > 单位规则)
  • 通过分治策略和状态管理,我们实现了符合金融规范的中文大写金额转换,满足了题目中的所有规则要求。

    作者:蜗牛的旷野

    物联沃分享整理
    物联沃-IOTWORD物联网 » 华为OD机试B卷人民币转换Python解法详解(附完整解题思路及满分攻略)

    发表回复