题解-数字字符串格式化

161 阅读3分钟

题解

这道题的核心在于对输入的数字字符串进行格式化处理,主要包括以下几个步骤:

  1. 去掉无用的前置零
  2. 提取整数部分和小数部分
  3. 对整数部分添加千分位逗号
  4. 拼接格式化后的整数部分和小数部分

下面,我们详细分析题目需求,并逐步优化代码。


问题分解与分析

  1. 去掉无用的前置零
    无用的前置零需要被移除,比如 "0000123.45" 需要转化为 "123.45"。可以通过从左到右遍历字符串,找到第一个非零字符的位置,截取子串即可。

  2. 分割整数和小数部分
    可以利用正则表达式匹配,提取出小数点之前的整数部分和小数点之后的小数部分。例如:

    • "1294512.12412" 分割后,整数部分为 "1294512",小数部分为 "12412"
    • 如果输入没有小数点,如 "987654321",则仅提取整数部分。
  3. 格式化整数部分
    Python 提供了一种简洁的方法来为整数添加千分位逗号,即 "{:,}".format(),直接对整数部分格式化即可。

  4. 拼接结果
    如果小数部分存在,需要将格式化后的整数部分和原始小数部分拼接;如果没有小数部分,则直接返回格式化后的整数部分。


代码实现

以下是代码,并附带注释:

import re

def solution(s: str) -> str:
    """
    将数字字符串格式化为带千分位的形式,保留小数部分,并去掉无用的前置零。
    """
    # 去除前导零,确保字符串至少为 "0"
    s = s.lstrip('0') or '0'
    
    # 分离整数部分和小数部分
    match = re.match(r'(\d+)(\.\d+)?', s)
    if not match:
        return "Invalid input"
    
    # 提取整数部分和小数部分
    integer_part = match.group(1)  # 整数部分
    decimal_part = match.group(2) or ''  # 小数部分,若无则为空字符串

    # 格式化整数部分
    formatted_integer = "{:,}".format(int(integer_part))
    
    # 拼接结果并返回
    return formatted_integer + decimal_part

# 测试样例
if __name__ == '__main__':
    assert solution("1294512.12412") == "1,294,512.12412"
    assert solution("0000123456789.99") == "1,234,567,889.99"
    assert solution("987654321") == "987,654,321"
    assert solution("0000") == "0"

代码详解

  1. 去除前导零

    • 使用 s.lstrip('0') 去除字符串中的前导零。如果字符串全是零,则保留一个零,利用 or '0' 处理这一特殊情况。
  2. 正则表达式分割

    • re.match(r'(\d+)(\.\d+)?', s) 将字符串分为整数部分和小数部分:
      • (\d+) 匹配一串数字,表示整数部分;
      • (\.\d+)? 匹配小数点后的一串数字,可选。
  3. 格式化整数部分

    • "{:,}".format(int(integer_part)) 自动为整数部分添加千分位逗号,简洁高效。
  4. 拼接结果

    • 如果小数部分存在(decimal_part 非空),直接拼接;否则仅返回格式化后的整数部分。

测试与验证

  1. 典型用例

    • 输入 "1294512.12412",返回 "1,294,512.12412"
    • 输入 "0000123456789.99",返回 "1,234,567,889.99"
    • 输入 "987654321",返回 "987,654,321"
  2. 边界用例

    • 输入 "0000",返回 "0"
    • 输入 ".1234",返回 "0.1234"
    • 输入 "0",返回 "0"
  3. 异常用例

    • 输入非法字符(如 "abc"),正则匹配失败,返回 "Invalid input"

复杂度分析

  1. 时间复杂度

    • 去除前导零的操作为 (O(n));
    • 正则匹配操作为 (O(n));
    • 整数部分格式化为 (O(m)),其中 (m) 是整数部分的长度。
    • 总体复杂度为 (O(n))。
  2. 空间复杂度

    • 使用了少量辅助变量,空间复杂度为 (O(1))。