问题描述
小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'
题目解析:
问题理解
你需要将一个不带千分位逗号的数字字符串转换为带千分位逗号的格式,并且保留小数部分。此外,输入的数字字符串前面可能会有无用的 0,这些也需要精简掉。
数据结构选择
- 使用
StringBuilder来高效地构建结果字符串。 - 使用
String来处理输入字符串和分离整数部分与小数部分。
算法步骤
-
去除前导零:
- 使用正则表达式
^0+(?!$)来去除字符串前面的无用0。
- 使用正则表达式
-
分离整数部分和小数部分:
- 使用
split("\\.")方法将字符串按小数点分割成整数部分和小数部分。
- 使用
-
处理整数部分:
- 从后往前遍历整数部分,每三位插入一个逗号。
- 使用
StringBuilder来高效地构建结果字符串。
-
合并结果:
- 将处理后的整数部分与小数部分合并,返回最终结果。
关键点
- 正则表达式的使用:
^0+(?!$)用于去除前导零。 - 从后往前遍历整数部分,每三位插入一个逗号。
代码详解:
public class Main { public static String solution(String s) { // 去除前导零 s = s.replaceFirst("^0+(?!$)", "");
// 分离整数部分和小数部分
String[] parts = s.split("\\.");
String integerPart = parts[0];
String decimalPart = parts.length > 1 ? "." + parts[1] : "";
// 处理整数部分,从后往前每三位插入一个逗号
StringBuilder sb = new StringBuilder();
int len = integerPart.length();
for (int i = 0; i < len; i++) {
// 每三位插入一个逗号
if (i > 0 && (len - i) % 3 == 0) {
sb.append(",");
}
sb.append(integerPart.charAt(i));
}
// 合并结果
return sb.toString() + decimalPart;
}
public static void main(String[] args) {
System.out.println(solution("1294512.12412").equals("1,294,512.12412"));
System.out.println(solution("0000123456789.99").equals("123,456,789.99"));
System.out.println(solution("987654321").equals("987,654,321"));
}
}
知识总结:
1. 去除前导零
- 代码使用了
replaceFirst方法配合正则表达式^0+(?!$)来去除输入字符串s开头的连续的零,但保留如果整个字符串就是单个零的情况。例如,输入 “00123” 会被转换为 “123”,而输入 “0” 则保持为 “0”。
2. 分离整数部分和小数部分
- 通过
split方法并以 “.” 作为分隔符,将输入字符串s拆分成整数部分和小数部分(如果有的话)。 - 将拆分后的整数部分存储在
integerPart变量中,小数部分根据是否存在(通过判断parts数组的长度是否大于 1),若存在则以 “.” 开头的形式存储在decimalPart变量中,否则decimalPart为空字符串。
3. 处理整数部分(添加逗号分隔)
- 使用
StringBuilder来高效地构建处理后的整数部分字符串。 - 通过循环遍历整数部分的每个字符,当满足条件(索引大于 0 且从后往前数每三位时),就向
StringBuilder中添加一个逗号。然后再将当前字符添加到StringBuilder中。
4. 合并结果
- 最后将处理好的整数部分(
sb.toString())和小数部分(decimalPart)进行合并并返回,得到最终格式化后的数字字符串。
学习计划
-
制定刷题计划
- 确定目标和范围:如果是学习数据结构和算法相关内容,可以根据不同的主题(如排序、搜索、统计等)来划分刷题范围。例如,针对本题涉及的统计数组中元素关系的类型,可以集中刷一批类似的题目。可以从简单到复杂,先从基础的数组遍历和统计题目开始,再到像本题这样有一定逻辑复杂度的题目。
- 安排时间:每天安排固定的时间用于刷题,比如每天 1 - 2 小时。可以将时间分成两部分,一部分用于新题目的练习,另一部分用于复习和总结之前做过的题目。在使用 MarsCode AI 刷题时,可以根据它提供的难度分级和题目类型分类来合理安排每个阶段的刷题量。
工具运用
-
结合 AI 刷题与其他学习资源
-
代码调试工具:结合代码调试工具(如 Java 中的调试器)和 MarsCode AI。当代码出现问题时,在 MarsCode AI 中分析错误信息后,可以使用调试工具来逐步执行代码,查看变量的值和程序的执行流程,更深入地理解代码的问题所在,尤其是对于像本题这种有一定逻辑复杂度的代码。
-