提问人:Evgeniy 提问时间:6/1/2022 最后编辑:dani-vtaEvgeniy 更新时间:6/1/2022 访问量:167
Codingbat 挑战:maxBlock
Codingbat challenge: maxBlock
问:
给定 CodingBat 的任务 maxBlock:
给定一个字符串,返回字符串中最大“块”的长度。块是一组相同的相邻字符。
maxBlock("hoopla") → 2
maxBlock("abbCCCddBBBxx") → 3
maxBlock("") → 0
我的解决方案通过了所有测试,但以下测试除外:
public int maxBlock(String str) {
int maxBlock = 0;
int currentBlock = 1;
if (str.length() < 1) {
return maxBlock;
} else {
maxBlock = 1;
}
for (int i = 0; i < str.length() - 1; i++) {
if (str.charAt(i) == str.charAt(i+1)) {
currentBlock++;
if (currentBlock > maxBlock) {
maxBlock = currentBlock;
currentBlock = 0;
}
}
}
return maxBlock;
}
答:
2赞
Robby Cornelissen
6/1/2022
#1
您未正确重置计数。如果以下字符与当前字符不同,则需要重置为。如果没有,您需要继续增加:currentBlock
currentBlock
1
currentBlock
public int maxBlock(String str) {
int maxBlock = 0;
int currentBlock = 1;
if (str.length() < 1) {
return maxBlock;
} else {
maxBlock = 1;
}
for (int i = 0; i < str.length() - 1; i++) {
if (str.charAt(i) == str.charAt(i+1)) {
currentBlock++;
if (currentBlock > maxBlock) {
maxBlock = currentBlock;
}
} else {
currentBlock = 1;
}
}
return maxBlock;
}
评论
0赞
user184868
6/1/2022
是的,但是从 1 数有点愚蠢。从 0 计数并返回 maxBlock+1 对我来说看起来更清楚
2赞
Robby Cornelissen
6/1/2022
@user184868同意。除此之外,还可以进行更多改进,但希望将我的更改保持在最低限度,以免混淆原始代码的问题所在。
1赞
Eskandar Abedini
6/1/2022
#2
此代码由 IntelliJ 的 GitHub Copilot 插件生成,您只需键入,然后 GitHub Copilot 生成其余代码:int maxBlock
private int maxBlock(String s) {
if (s == null || s.length() == 0) return 0;
int maxBlocks = 0;
int currentBlocks = 0;
char currentChar = s.charAt(0);
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == currentChar) {
currentBlocks++;
} else {
currentBlocks = 1;
currentChar = s.charAt(i);
}
maxBlocks = Math.max(maxBlocks, currentBlocks);
}
return maxBlocks;
}
我只添加到生成的代码中。if (s == null || s.length() == 0) return 0;
评论
0赞
Viktor Mellgren
6/1/2022
并没有真正向操作解释问题是什么
2赞
dani-vta
6/1/2022
#3
虽然我认为 @Robby Cornelissen 和 @Eskandar Abedini 的解决方案肯定比我的解决方案更可行,并且更接近原始代码,但我想通过使用正则表达式和一些编码逻辑来提供一种不同的方法。
以下正则表达式查找字符重复出现 0 次或多次的匹配项。这可以与类的方法一起使用,以提取找到的最长匹配项。results()
Matcher
这是测试正则表达式的链接
https://regex101.com/r/OcMoQ9/1
代码实现
List<String> testCase = List.of("hoopla", "abbCCCddBBBxx", "", "xyz", "xxyz", "xyzz", "abbbcbbbxbbbx", "XXBBBbbxx", "XXBBBbbxxXXXX", "XX2222BBBbbXX2222");
Pattern pattern = Pattern.compile("(.)(\\1*)");
Matcher matcher;
for (String s : testCase) {
matcher = pattern.matcher(s);
System.out.printf("%s => %d%n", s, matcher
.results()
.map(match -> match.group().length())
.max(Comparator.comparing(Integer::intValue))
.orElse(0));
}
//Or even simpliefied like so as @Holger has pointed out in the comments
for (String s : testCase) {
matcher = pattern.matcher(s);
System.out.printf("%s => %d%n", s, matcher
.results()
.mapToInt(match -> match.group().length())
.max()
.orElse(0));
}
用于测试代码的链接
https://www.jdoodle.com/iembed/v0/rH7
输出
hoopla => 2
abbCCCddBBBxx => 3
=> 0
xyz => 1
xxyz => 2
xyzz => 2
abbbcbbbxbbbx => 3
XXBBBbbxx => 3
XXBBBbbxxXXXX => 4
XX2222BBBbbXX2222 => 4
评论
2赞
Holger
6/1/2022
你不需要像这样的结构,你可以简单地用来比较对象。然而,更简单的是使用Comparator.comparing(Integer::intValue)
Comparator.naturalOrder()
Integer
.mapToInt(match -> match.group().length()) .max() .orElse(0)
评论