这段代码可以正常工作,但是我正在寻找一种优化它的方法。如果查看长字符串,可以看到“ l”连续出现五次。没有其他角色连续多次出现。因此,输出为5。现在,问题是此方法检查每个字符,即使找到最大值,它也会继续检查其余字符。有没有更有效的方法?
public class Main {
public static void main(String[] args) {
System.out.println(longestStreak("KDDiiigllllldddfnnlleeezzeddd"));
}
private static int longestStreak(String str) {
int max = 0;
for (int i = 0; i < str.length(); i++) {
int count = 0;
for (int j = i; j < str.length(); j++) {
if (str.charAt(i) == str.charAt(j)) {
count++;
} else break;
}
if (count > max) max = count;
}
return max;
}
}
答案 0 :(得分:3)
我们可以在单次迭代中为先前的字符数添加变量。另外,如果i + max - currentLenght < str.length()
,我们将停止迭代。这意味着无法更改最大值:
private static int longestStreak(String str) {
int maxLenght = 0;
int currentLenght = 1;
char prev = str.charAt(0);
for (int index = 1; index < str.length() && isMaxCanBeChanged(str, maxLenght, currentLenght, index); index++) {
char currentChar = str.charAt(index);
if (currentChar == prev) {
currentLenght++;
} else {
maxLenght = Math.max(maxLenght, currentLenght);
currentLenght = 1;
}
prev = currentChar;
}
return Math.max(maxLenght, currentLenght);
}
private static boolean isMaxCanBeChanged(String str, int max, int currentLenght, int index) {
return index + max - currentLenght < str.length();
}
答案 1 :(得分:1)
是的。 C ++代码:
string str = "KDDiiigllllldddfnnlleeezzeddd";
int longest_streak = 1, current_streak = 1; char longest_letter = str[0];
for (int i = 1; i < str.size(); ++i) {
if (str[i] == str[i - 1])
current_streak++;
else current_streak = 1;
if (current_streak > longest_streak) {
longest_streak = current_streak;
longest_letter = str[i];
}
}
cout << "The longest streak is: " << longest_streak << " and the character is: " << longest_letter << "\n";
LE:如果需要,我可以提供它的Java代码,但我认为您可以理解。
public class Main {
public static void main(String[] args) {
System.out.println(longestStreak("KDDiiigllllldddfnnlleeezzeddd"));
}
private static int longestStreak(String str) {
int longest_streak = 1, current_streak = 1; char longest_letter = str.charAt(0);
for (int i = 1; i < str.length(); ++i) {
if (str.charAt(i) == str.charAt(i - 1))
current_streak++;
else current_streak = 1;
if (current_streak > longest_streak) {
longest_streak = current_streak;
longest_letter = str.charAt(i);
}
}
return longest_streak;
}
}
答案 2 :(得分:0)
这是一个正则表达式魔术解决方案,尽管有些蛮力可能会获得一些布朗尼分数。我们可以从原始输入中的字符数开始迭代,一次减少一个,尝试对该长度的连续字符进行正则表达式替换。如果替换有效,那么我们知道条纹最长。
String input = "KDDiiigllllldddfnnlleeezzeddd";
for (int i=input.length(); i > 0; --i) {
String replace = input.replaceAll(".*?(.)(\\1{" + (i-1) + "}).*", "$1");
if (replace.length() != input.length()) {
System.out.println("longest streak is: " + replace);
}
}
此打印:
longest streak is: lllll
答案 3 :(得分:0)
可以将循环重写得更小一些,但主要是可以优化条件:
i < str.length() - max
答案 4 :(得分:0)
使用Stream和Collector。它应该给出所有重复的最高元素。
代码:
String lineString = "KDDiiiiiiigllllldddfnnlleeezzeddd";
String[] lineSplit = lineString.split("");
Map<String, Integer> collect = Arrays.stream(lineSplit)
.collect(Collectors.groupingBy(Function.identity(), Collectors.summingInt(e -> 1)));
int maxValueInMap = (Collections.max(collect.values()));
for (Entry<String, Integer> entry : collect.entrySet()) {
if (entry.getValue() == maxValueInMap) {
System.out.printf("Character: %s, Repetition: %d\n", entry.getKey(), entry.getValue());
}
}
输出:
Character: i, Repetition: 7
Character: l, Repetition: 7
P.S我不确定这段代码的效率如何。我刚刚学习了Streams。