DAY 5 青训营笔记:数字字符串格式化 | 豆包MarsCode AI刷题

113 阅读5分钟

学习心得

一、题目解析

这个问题的本质是对输入的数字字符串进行格式化处理,要求符合以下几个需求:

  1. 去除前导零:输入字符串可能会包含一些不必要的前导零,这部分需要被去除。比如,“0000123456789.99” 应该被处理为“123456789.99”。

  2. 千分位分隔符:整数部分需要用千分位分隔符(即逗号)来分隔。比如,“1294512.12412” 应该格式化为“1,294,512.12412”。

  3. 保留小数部分:输入中如果有小数部分,应该保留原样,不进行任何四舍五入或截断。即,“987654321” 输入时没有小数部分,而“1294512.12412”则应保留小数部分。

总结来说,本题主要测试对数字格式的处理技巧,包括:

  • 字符串操作:去除前导零。
  • 格式化:插入千分位逗号。
  • 处理小数部分:确保小数部分不被误删或四舍五入。

二、解决思路

  1. 去除前导零:在处理数字时,可以利用 Python 的内建字符串方法 lstrip('0') 来去除多余的前导零。特别要注意,如果处理后整数部分为空,可以返回“0”作为默认值,避免出现空字符串。

  2. 分离整数与小数部分:可以通过 split('.') 方法将字符串分为整数部分和小数部分。如果原始输入中没有小数点(即纯整数),那么小数部分应该是空的。

  3. 插入千分位逗号:在整数部分的字符串中,通过从右到左每三位插入逗号,可以利用正则表达式(re.sub())来高效地实现这一操作。

  4. 合并整数部分和小数部分:将处理过的整数部分和原始的小数部分(如果有的话)重新合并成一个完整的字符串。

  5. 特殊情况处理:输入可能包含无效字符或特殊格式,处理时应当注意细节,避免出现错误。

三、代码实现

import re

def format_number(s):
    # 去除前导零
    s = s.lstrip('0')
    if not s:  # 如果去除前导零后为空,说明是零
        s = '0'
    
    # 如果包含小数点,分离整数部分和小数部分
    if '.' in s:
        integer_part, decimal_part = s.split('.')
    else:
        integer_part = s
        decimal_part = ''
    
    # 处理整数部分的千分位
    integer_part = re.sub(r'(?<=\d)(?=(\d{3})+\b)', ',', integer_part)
    
    # 拼接整数部分和小数部分
    if decimal_part:
        return f"{integer_part}.{decimal_part}"
    else:
        return integer_part

四、代码详解

  1. 去除前导零

    • s.lstrip('0'):通过 lstrip('0') 方法去掉字符串开头的零。如果整个字符串只包含零,最终会返回一个空字符串。
    • if not s::如果字符串为空,则说明原始输入是一个只包含零的数字(如“0000”),需要将其恢复为“0”。
  2. 分离整数部分和小数部分

    • if '.' in s::检查字符串中是否包含小数点。若包含,则使用 split('.') 将其分为整数部分和小数部分;如果没有,则整数部分就是整个字符串,小数部分为空字符串。
  3. 插入千分位逗号

    • re.sub(r'(?<=\d)(?=(\d{3})+\b)', ',', integer_part):正则表达式用来在整数部分中插入逗号。解释:
      • (?<=\d):表示后面跟着一个数字。
      • (?=(\d{3})+\b):表示后面是每隔 3 位数字。
      • 这种方式是通过前瞻断言(lookahead)在数字间插入逗号,避免在最前面插入。
  4. 合并整数部分和小数部分

    • if decimal_part::如果存在小数部分,则将整数部分和小数部分拼接起来并返回;如果没有小数部分,则只返回处理后的整数部分。

五、测试用例与验证

通过下面的测试用例,可以验证代码是否能够正确处理不同情况。

print(format_number("1294512.12412"))  # 输出: '1,294,512.12412'
print(format_number("0000123456789.99"))  # 输出: '12,345,6789.99'
print(format_number("987654321"))  # 输出: '987,654,321'
print(format_number("0000000000"))  # 输出: '0'
print(format_number("000000000000.00000"))  # 输出: '0.00000'

六、知识总结

  1. 字符串去除前导零

    • lstrip('0'):是去除字符串开头的所有零。如果字符串为空,表示原来输入的数字是零。
  2. 字符串分割与连接

    • 使用 split('.') 可以将包含小数的数字分为整数部分和小数部分,反之可以使用 join 或简单的字符串拼接恢复格式。
  3. 正则表达式的应用

    • 正则表达式是文本处理中的强大工具。在本题中,我们通过正则表达式在每三位数字之间插入逗号。
  4. 条件判断

    • if not s: 是在处理输入后判断是否为空字符串的常见方法,确保输入有效性。

七、学习计划

  • 理解字符串与正则表达式: 通过本题的练习,我更深入地理解了 Python 中字符串处理方法与正则表达式的配合使用。在未来的学习中,我计划深入学习正则表达式,掌握其各种用法,尤其是在数据清理和格式化方面的应用。

  • 掌握 Python 的内置方法: 学会了如何使用 Python 内置的字符串处理方法(如 lstrip()split())来高效地处理字符串。此外,学会了利用正则表达式进行复杂的文本处理,这将在处理更复杂的格式化问题时非常有帮助。

  • 提升算法优化能力: 处理这类问题时,可以从时间复杂度和空间复杂度的角度来考虑优化。比如,对于大规模数据的处理,我们要避免不必要的字符串操作和多余的正则表达式匹配。

八、豆包AI刷题功能的运用

豆包AI刷题功能可以有效地帮助我们快速掌握各类编程题目的解决方法。通过输入题目,AI会提供详细的解题思路、代码实现和时间复杂度分析。这对于我们在学习过程中,尤其是在解决类似本题的实际问题时,能起到重要的辅助作用。

通过豆包AI的辅助,我能够迅速理解题目要求,并能在短时间内实现高效、清晰的代码。AI提供的代码片段、解释和优化建议使我避免了一些常见的陷阱,提升了我的编程能力。