31不同整数的技术问题-青训营刷题
问题描述
小R有一个字符串 word
,该字符串由数字和小写英文字母组成。小R想用空格替换每一个不是数字的字符。然后,他希望统计在替换后剩下的整数中,不同整数的数目。
例如,给定字符串 "a123bc34d8ef34"
,替换后形成的字符串是 " 123 34 8 34"
,剩下的整数是 "123"
、"34"
、"8"
和 "34"
。不同的整数有三个,即 "123"
、"34"
和 "8"
。
注意,只有当两个整数的不含前导零的十进制表示不同,才认为它们是不同的整数。
测试样例
样例1:
输入:
word = "a123bc34d8ef34"
输出:3
样例2:
输入:
word = "t1234c23456"
输出:2
样例3:
输入:
word = "a1b01c001d4"
输出:2
代码如下
import java.util.HashSet;
import java.util.Set;
public class Main {
public static void main(String[] args) {
System.out.println(solution("a123bc34d8ef34") == 3);
System.out.println(solution("t1234c23456") == 2);
System.out.println(solution("a1b01c001d4") == 2);
}
public static int solution(String word) {
// 用集合存储不同的整数
Set<String> uniqueNumbers = new HashSet<>();
StringBuilder currentNumber = new StringBuilder(); // 临时变量,用来拼接数字
for (char ch : word.toCharArray()) {
if (Character.isDigit(ch)) {
currentNumber.append(ch);
} else {
// 如果遇到非数字字符,处理当前数字
if (currentNumber.length() > 0) {
// 去除前导零并加入到 set 中
while (currentNumber.length() > 1 && currentNumber.charAt(0) == '0') {
currentNumber.deleteCharAt(0);
}
uniqueNumbers.add(currentNumber.toString());
currentNumber.setLength(0); // 清空 StringBuilder
}
}
}
// 遇到非数字才会处理数字,所以要处理字符串最后的数字
if (currentNumber.length() > 0) {
// 去除前导零并加入到 set 中
while (currentNumber.length() > 1 && currentNumber.charAt(0) == '0') {
currentNumber.deleteCharAt(0);
}
uniqueNumbers.add(currentNumber.toString());
}
return uniqueNumbers.size();
}
}
代码解释
好的!这段代码的功能是从一个字符串中提取所有不同的数字,并返回这些数字的数量。以下是代码的详细解释:
代码功能
给定一个字符串,例如 "a123bc34d8ef34"
,代码会提取其中的所有数字(如 123
、34
、8
、34
),并去除重复的数字,最终返回不同数字的数量。在这个例子中,不同数字有 123
、34
和 8
,因此返回 3
。
代码逻辑
代码的核心逻辑是逐字符遍历字符串,识别数字并去除重复项。以下是详细步骤:
1. 数据结构
-
Set<String> uniqueNumbers
:用于存储提取到的不同数字。Set
是一种不允许重复元素的集合,因此它会自动去除重复的数字。 -
StringBuilder currentNumber
:用于临时存储当前正在提取的数字。StringBuilder
是一个可变的字符串类,可以动态地拼接字符。
2. 遍历字符串
代码通过 for (char ch : word.toCharArray())
遍历输入字符串中的每一个字符。
3. 判断字符是否为数字
-
使用
Character.isDigit(ch)
判断当前字符是否为数字。-
如果是数字(如
'1'
、'2'
等),将其添加到currentNumber
中。 -
如果不是数字(如字母或符号),则进入下一步处理。
-
4. 处理当前数字
当遇到非数字字符时,说明当前的数字已经结束,需要对 currentNumber
中的数字进行处理:
-
去除前导零:如果
currentNumber
中的数字以0
开头(如0123
),需要去掉前导零,只保留有效数字部分(如123
)。-
使用
while (currentNumber.length() > 1 && currentNumber.charAt(0) == '0')
来判断和删除前导零。
-
-
添加到集合:将处理后的数字添加到
uniqueNumbers
集合中。 -
清空
currentNumber
:为了开始提取下一个数字,需要清空currentNumber
。
5. 处理字符串末尾的数字
遍历结束后,currentNumber
中可能还存储着最后一个数字(如果字符串以数字结尾)。因此,需要再执行一次上述的处理逻辑,确保最后一个数字也被正确处理。
6. 返回结果
最后,返回 uniqueNumbers
集合的大小,即不同数字的数量。
代码示例说明
以字符串 "a1b01c001d4"
为例,逐步解释代码的执行过程:
-
初始化:
-
uniqueNumbers
是一个空集合。 -
currentNumber
是一个空的StringBuilder
。
-
-
遍历字符串:
-
遍历到
'a'
:不是数字,跳过。 -
遍历到
'1'
:是数字,添加到currentNumber
,此时currentNumber = "1"
。 -
遍历到
'b'
:不是数字,处理currentNumber
:-
去除前导零(没有前导零,跳过)。
-
将
"1"
添加到uniqueNumbers
。 -
清空
currentNumber
。
-
-
遍历到
'0'
:是数字,添加到currentNumber
,此时currentNumber = "0"
。 -
遍历到
'1'
:是数字,添加到currentNumber
,此时currentNumber = "01"
。 -
遍历到
'c'
:不是数字,处理currentNumber
:-
去除前导零,变为
"1"
。 -
将
"1"
添加到uniqueNumbers
,但由于"1"
已经存在,不会重复添加。 -
清空
currentNumber
。
-
-
遍历到
'0'
:是数字,添加到currentNumber
,此时currentNumber = "0"
。 -
遍历到
'0'
:是数字,添加到currentNumber
,此时currentNumber = "00"
。 -
遍历到
'1'
:是数字,添加到currentNumber
,此时currentNumber = "001"
。 -
遍历到
'd'
:不是数字,处理currentNumber
:-
去除前导零,变为
"1"
。 -
将
"1"
添加到uniqueNumbers
,同样不会重复添加。 -
清空
currentNumber
。
-
-
遍历到
'4'
:是数字,添加到currentNumber
,此时currentNumber = "4"
。 -
遍历结束,处理最后一个数字:
-
去除前导零(没有前导零,跳过)。
-
将
"4"
添加到uniqueNumbers
。
-
-
-
最终结果:
-
uniqueNumbers
中存储了"1"
和"4"
,共 2 个不同的数字。 -
返回
2
。
-
总结
这段代码的核心思想是:
-
遍历字符串,逐字符判断是否为数字。
-
遇到数字时,将其拼接到临时变量中。
-
遇到非数字时,处理临时变量中的数字(去除前导零并添加到集合中)。
-
最后返回集合中不同数字的数量。
通过这种方式,代码能够高效地提取并统计字符串中的不同数字。