如何使用Java SReam找到最长的重复子弦?
对于学校作业,我必须实现一种方法,该方法将从字符串中返回最长的重复子字符串。但是我必须仅使用流API来做到这一点。
这是我到目前为止所做的:
public static String biggestRedundantSubstring(String s) {
Stream.Builder<String> stringBuilder = Stream.builder();
while (!Objects.equals(s, "")) {
stringBuilder.add(s);
s = s.substring(1);
}
return stringBuilder.build().sorted().reduce("",
(String biggestRedundantSubstring, String matchingPrefix) ->
biggestRedundantSubstring.length() > matchingPrefix.length() ?
biggestRedundantSubstring : matchingPrefix,
(String sub1, String sub2) -> {
String matchingPrefix = "";
int limitIndex = Math.max(sub1.length(), sub2.length()) - 1;
for (int i = 0; i < limitIndex; i++) {
if (sub1.charAt(i) == sub2.charAt(i)) {
matchingPrefix += sub1.charAt(i);
} else {
break;
}
}
return matchingPrefix;
});
}
这是main()
方法:
public static void main(String[] args) {
if (args.length != 0) {
for (String s : args) {
System.out.println(s + " " + biggestRedundantSubstring(s));
}
} else {
String s = "ababaac";
System.out.println(s + " " + biggestRedundantSubstring(s));
}
}
没有参数的情况应该在控制台上打印:
ababaac aba
但是它打印出来:
ababaac ababaac
所以我想知道是否可能吗?我还尝试使用三个参数使用redy()
,但它也不起作用,我可以在流外部使用一个变量来跟踪和更改“ braderedredendansubstring”的值可变,但这违背了为什么使用流,不是吗?
For a school assignment, I have to implement a method that will return the longest repeated substring from a string. But I have to do it by using only the Stream API.
This is what I have done so far:
public static String biggestRedundantSubstring(String s) {
Stream.Builder<String> stringBuilder = Stream.builder();
while (!Objects.equals(s, "")) {
stringBuilder.add(s);
s = s.substring(1);
}
return stringBuilder.build().sorted().reduce("",
(String biggestRedundantSubstring, String matchingPrefix) ->
biggestRedundantSubstring.length() > matchingPrefix.length() ?
biggestRedundantSubstring : matchingPrefix,
(String sub1, String sub2) -> {
String matchingPrefix = "";
int limitIndex = Math.max(sub1.length(), sub2.length()) - 1;
for (int i = 0; i < limitIndex; i++) {
if (sub1.charAt(i) == sub2.charAt(i)) {
matchingPrefix += sub1.charAt(i);
} else {
break;
}
}
return matchingPrefix;
});
}
And this is the main()
method:
public static void main(String[] args) {
if (args.length != 0) {
for (String s : args) {
System.out.println(s + " " + biggestRedundantSubstring(s));
}
} else {
String s = "ababaac";
System.out.println(s + " " + biggestRedundantSubstring(s));
}
}
This without arguments should print on console:
ababaac aba
But instead it prints:
ababaac ababaac
So I was wondering if it is possible? I also tried to use reduce()
with three parameters, but it doesn't work either, and I could use a variable outside of the stream to keep track of and change the value of the "biggestRedundantSubstring" variable, but it kind of goes against why to use streams, doesn't it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
首先,让我们描述总体算法:
我们需要生成所有可能的 substring 。 IE对于
0
到str.length() - 1
的字符串的每个有效索引1
tostr.length() - 索引
。然后,我们需要检查以下 substring 不止一次出现并选择最长的子字符串。
要生成所有子字符串,我们需要使用Nested
intstream
浏览所有有效的索引(可以使用循环的嵌套进行相同的操作)。当我们拥有所有可能的开始和结束索引时,我们可以将它们变成 substrings 。
然后,为了找出这些子字符串不止一次出现,我们可以使用映射
map&lt; string,boolean&gt;
,其中键将是字符串本身和a < em> value 映射到每个键将表示是否重复。我们可以使用 collector “ nofollow noreferrer”> 。然后,当我们需要在辅助地图的条目上创建流时。滤除重复的条目,然后使用
max()
操作选择具有最高长度的条目,该操作返回可选对象并期望比较器
作为参数。这就是外观:
main()
输出:
Firstly, let's describe the overall algorithm:
We need to generate all possible substrings. I.e. for every valid index of the string from
0
up tostr.length() - 1
we have to construct all substrings having the length from1
tostr.length() - index
.Then we need to check which of these substrings occur more than once and pick the longest of them.
To generate all substring, we need to walk through all the valid indices using nested
IntStream
(the same can be done using a nestedfor
loop). And when we have all the possible starting and ending indices, we can turn them into substrings.Then to find out which of these substrings appear more than once, we can use a map
Map<String,Boolean>
, in which keys would be the strings itself and a value mapped to each key would signify whether it's repeated or not. We can do this by using collectortoMap(keyMapper,valueMapper,mergeFunction)
.Then when we need to create a stream over the entries of the auxiliary map. Filter out repeated entries and pick the one that has the highest length by using
max()
operation that returns an Optional object and expects aComparator
as an argument.That's how it might look like:
main()
Output: