数字字符串格式化
问题描述
小M在工作时遇到了一个问题,他需要将用户输入的不带千分位逗号的数字字符串转换为带千分位逗号的格式,并且保留小数部分。小M还发现,有时候输入的数字字符串前面会有无用的 0,这些也需要精简掉。请你帮助小M编写程序,完成这个任务。
测试样例
样例1:
输入:s = "1294512.12412"
输出:'1,294,512.12412'
样例2:
输入:s = "0000123456789.99"
输出:'123,456,789.99'
样例3:
输入:s = "987654321"
输出:'987,654,321'
为了完成这个任务,我们可以将数字字符串格式化为带千分位逗号的形式,并且去掉无用的前导零。我们需要考虑以下步骤:
- 去掉前导零:如果输入字符串是类似
0000123456的形式,我们需要去掉所有的前导零。 - 处理小数部分:小数部分需要保留原样,但整数部分需要加上千分位逗号。
- 插入千分位逗号:整数部分每隔 3 个数字插入一个逗号。
- 结合整数部分和小数部分:如果存在小数部分,将整数部分和小数部分拼接成最终结果。
思路
- 去掉字符串开头的无用零(可以用
lstrip('0')方法)。 - 使用字符串分割(
split)将整数部分和小数部分分开(如果有小数)。 - 对整数部分进行千分位格式化,使用 Python 内置的
format()函数或字符串的f-string格式化。 - 将整数部分和小数部分重新拼接。
代码实现
def format_number(s: str) -> str:
# 去掉前导零
s = s.lstrip('0')
# 如果去掉零之后字符串为空,说明输入是 0,返回 "0"
if not s:
return "0"
# 分割整数部分和小数部分
if '.' in s:
integer_part, decimal_part = s.split('.')
else:
integer_part, decimal_part = s, ""
# 格式化整数部分,加上千分位逗号
integer_part = "{:,}".format(int(integer_part))
# 拼接整数部分和小数部分
if decimal_part:
return f"{integer_part}.{decimal_part}"
else:
return integer_part
代码解释
- 去掉前导零:
s.lstrip('0')会去除字符串s开头的所有零。 - 处理空字符串:如果去掉零后字符串为空,说明输入是
0,此时返回"0"。 - 分割整数部分和小数部分:通过
split('.')来分离整数和小数部分,integer_part是整数部分,decimal_part是小数部分。 - 格式化整数部分:使用 Python 的
"{:,}".format(int(integer_part))来为整数部分添加千分位逗号。 - 拼接:将整数部分和小数部分拼接成最终的格式化字符串。
测试用例
print(format_number("1294512.12412")) # 输出: '1,294,512.12412'
print(format_number("0000123456789.99")) # 输出: '123,456,789.99'
print(format_number("987654321")) # 输出: '987,654,321'
print(format_number("0000")) # 输出: '0'
print(format_number("0.00123")) # 输出: '0.00123'
测试结果
- 样例 1
s = "1294512.12412":去掉无用的零并格式化为千分位,输出'1,294,512.12412'。 - 样例 2
s = "0000123456789.99":去掉前导零并格式化为千分位,输出'123,456,789.99'。 - 样例 3
s = "987654321":去掉前导零并格式化为千分位,输出'987,654,321'。
复杂度分析
- 时间复杂度:
O(n),其中n是输入字符串的长度。处理字符串的操作(去掉前导零、分割、格式化)都只需要线性时间。 - 空间复杂度:
O(n),因为我们需要处理并存储格式化后的字符串。
总结
此算法通过简单的字符串操作和内置的格式化功能,能够高效地完成数字字符串的格式化任务,包括去掉前导零并添加千分位逗号,同时保留小数部分。