题目描述
小R有一个字符串 word,该字符串由数字和小写英文字母组成。小R想用空格替换每一个不是数字的字符。然后,他希望统计在替换后剩下的整数中,不同整数的数目。
例如,给定字符串 "a123bc34d8ef34",替换后形成的字符串是 " 123 34 8 34",剩下的整数是 "123"、"34"、"8" 和 "34"。不同的整数有三个,即 "123"、"34" 和 "8"。
注意,只有当两个整数的不含前导零的十进制表示不同,才认为它们是不同的整数。
示例
- 输入:
word = "a123bc34d8ef34"- 输出:3
- 输入:
word = "t1234c23456"- 输出:2
- 输入:
word = "a1b01c001d4"- 输出:2
解题思路
分析需求
- 输入:一个字符串
word,由数字和小写英文字母组成。 - 输出:一个整数,表示替换后剩下的不同整数的数目。
关键点
- 替换非数字字符:将字符串中所有非数字字符替换为空格。
- 提取整数:使用正则表达式提取所有被空格分隔的整数。
- 去除前导零:去除每个整数的前导零,确保整数的唯一性。
- 统计不同整数:使用集合来存储不同的整数,并返回集合的大小。
算法步骤
- 替换非数字字符:
- 使用
replaceAll方法将所有非数字字符替换为空格。
- 使用
- 提取整数:
- 使用
split方法按空格分割字符串,得到一个包含所有整数的数组。
- 使用
- 去除前导零:
- 使用正则表达式
replaceFirst("^0+(?!$)", "")去除每个整数的前导零。
- 使用正则表达式
- 统计不同整数:
- 使用
HashSet存储不同的整数,确保每个整数只被统计一次。
- 使用
- 返回结果:
- 返回集合的大小,即不同整数的数量。
代码解析
import java.util.HashSet;
import java.util.Set;
class Main {
public static int solution(String word) {
// 1. 替换非数字字符为空格
String processedWord = word.replaceAll("[^0-9]", " ");
// 2. 使用正则表达式提取所有整数
String[] numbers = processedWord.split("\\s+");
// 3. 使用 HashSet 存储不同的整数
Set<String> uniqueNumbers = new HashSet<>();
for (String num : numbers) {
// 4. 去除前导零并添加到集合中
if (!num.isEmpty()) {
uniqueNumbers.add(num.replaceFirst("^0+(?!$)", ""));
}
}
// 5. 返回不同整数的数量
return uniqueNumbers.size();
}
public static void main(String[] args) {
// 添加测试用例
System.out.println(solution("a123bc34d8ef34") == 3);
System.out.println(solution("t1234c23456") == 2);
System.out.println(solution("a1b01c001d4") == 2);
}
}
- 替换非数字字符:使用
replaceAll("[^0-9]", " ")将所有非数字字符替换为空格。 - 提取整数:使用
split("\\s+")按空格分割字符串,得到一个包含所有整数的数组。 - 去除前导零:使用
replaceFirst("^0+(?!$)", "")去除每个整数的前导零。 - 统计不同整数:使用
HashSet存储不同的整数,确保每个整数只被统计一次。 - 返回结果:返回集合的大小,即不同整数的数量。
学习心得
1. 理解问题的本质
在解决这个问题时,首先要理解问题的本质,即如何从一个包含数字和字母的字符串中提取出所有的整数,并统计不同整数的数量。通过明确这一点,我们可以更容易地设计算法来解决问题。
2. 正则表达式的应用
正则表达式是处理字符串问题的强大工具。在这个问题中,我们使用了 replaceAll 和 split 方法来处理字符串,并使用 replaceFirst 方法去除前导零。这些方法不仅简洁,而且高效。
3. 集合的使用
集合是一种非常有用的容器,它可以自动去重并存储唯一的元素。在这个问题中,我们使用 HashSet 来存储不同的整数,确保每个整数只被统计一次。这种做法不仅简单明了,而且效率高。
4. 边界条件的处理
在处理字符串问题时,需要注意边界条件的处理。特别是当字符串为空或全是字母时,需要确保程序能够正确处理这些情况。在这个问题中,我们通过检查 num.isEmpty() 来避免空字符串的干扰。
5. 测试用例的重要性
编写测试用例可以帮助我们验证算法的正确性。在这个问题中,我们提供了几个典型的测试用例,确保我们的算法能够处理各种边界情况。通过这些测试用例,我们可以及时发现和修复潜在的问题。
总结
通过解决这个问题,我深刻体会到了算法设计的重要性。合理的算法设计不仅可以提高程序的效率,还可以使代码更加清晰和易于维护。同时,我也学会了如何通过正则表达式和集合来优化算法,这对于解决复杂问题非常有帮助。在未来的学习和工作中,我会继续努力提升自己的算法能力,以应对更多挑战。