對于學校作業,我必須實作一個方法,該方法將回傳字串中最長的重復子字串。但我必須只使用 Stream 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
所以我想知道這是否可能?我也嘗試使用reduce()
三個引數,但它也不起作用,我可以使用流外部的變數來跟蹤和更改“biggestRedundantSubstring”變數的值,但這有點違背為什么要使用流,不是嗎?
uj5u.com熱心網友回復:
首先,讓我們描述一下整體演算法:
我們需要生成所有可能的子字串。即對于字串 from 的每個有效索引,
0
我們str.length() - 1
必須構造所有長度為 from to的子字串。1
str.length() - index
然后我們需要檢查這些子字串中的哪些出現了多次,并選擇其中最長的。
要生成所有子字串,我們需要使用嵌套遍歷所有有效索引(使用嵌套回圈IntStream
也可以這樣做)。for
當我們擁有所有可能的開始和結束索引時,我們可以將它們轉換為子字串。
然后要找出這些子字串中的哪些出現多次,我們可以使用 map Map<String,Boolean>
,其中鍵是字串本身,映射到每個鍵的值表示它是否重復。我們可以通過使用收集器來做到這一點。 toMap(keyMapper,valueMapper,mergeFunction)
然后當我們需要在輔助映射的條目上創建一個流時。max()
通過使用回傳 Optional 物件并期望 aComparator
作為引數的操作,過濾掉重復的條目并選擇具有最高長度的條目。
這就是它的樣子:
public static String biggestRedundantSubstring(String str) {
return IntStream.range(0, str.length()) // generating starting indices
.boxed()
.flatMap(start -> IntStream.rangeClosed(start 1, str.length()).mapToObj(end -> str.substring(start, end))) // generating ending indices and turning each combination of `start` and `end` into a substring
.collect(Collectors.toMap( // creating an intermediate map Map<String, Boolean>
Function.identity(),
s -> false, // is repeated substring = false, because element has been encountered for the first time
(v1, v2) -> true // substring has been encountered more than once, i.e. is proved to be repeated
))
.entrySet().stream()
.filter(Map.Entry::getValue) // filtering the repeated substrings
.max(Map.Entry.comparingByKey(Comparator.comparingInt(String::length))) // returns Optional<Map.Entry<String, Boolean>>
.map(Map.Entry::getKey) // returns Optional<String>
.orElse(""); // if Optional is empty return an empty string
}
main()
public static void main(String[] args) {
String s = "ababaac";
System.out.println(s " " biggestRedundantSubstring(s));
}
輸出:
ababaac aba
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/496610.html
上一篇:根據最大值和最小值生成間隔