需要找到短语中每个句子的最大单词数。句子用?.!
符号分隔。
我几乎已经完成了这项任务,但是我坚持以纯Java 8的方式来完成它,您能帮我吗?
public static void main(String[] args) {
assert solution("We test coders. Give us a try?") == 4;
assert solution("Forget CVs..Save time . x x") == 2;
assert solution("Some some! time . x x") == 2;
}
public static int solution(String S) {
return Arrays.stream(S.split("[.!?]"))
.map(String::trim)
.filter(s -> !s.isEmpty())
.max(Comparator.comparingInt(o -> o.split(" ").length))
.map(s -> s.split(" "))
.flatMap(...); // <-- what to do here?
}
答案 0 :(得分:4)
我将从Java 9开始使用
// preparation, these can be static final variables
Pattern sentence = Pattern.compile("[^.?!]+"), word = Pattern.compile("\\w+");
和
int maxWordsPerSentence = sentence.matcher(string).results()
.mapToInt(s -> (int)word.matcher(s.group()).results().count())
.max().orElse(0);
流式传输预期的匹配很简单,因为现在,我们不需要过滤空字符串,因为不匹配的流将正确报告零计数。
您可以使用this answer中的results()
实现在Java 8中使用类似的逻辑。您只需要将代码更改为
int maxWordsPerSentence = results(sentence.matcher(string))
.mapToInt(s -> (int)results(word.matcher(s.group())).count())
.max().orElse(0);
改为调用static
方法。
答案 1 :(得分:2)
Pattern p = Pattern.compile("[.!?]");
System.out.println(p.splitAsStream(s)
.mapToInt(str -> (int) Arrays.stream(str.split(" "))
.filter(x -> !x.trim().isEmpty())
.count())
.max()
.orElse(0));
从Java-11开始使用Predicate::not
,这将更具可读性:
Pattern p = Pattern.compile("[.!?]");
System.out.println(p.splitAsStream(s)
.mapToInt(str -> (int) Arrays.stream(str.split(" "))
.map(String::trim)
.filter(Predicate.not(String::isEmpty))
.count())
.max()
.orElse(0));
答案 2 :(得分:2)
只需用"\\s+"
分隔单词(因此您将忽略多个空格字符)。然后从max()
获取IntStream
的值。
Arrays.stream(str.split("[.!?]"))
.map(String::trim)
.filter(s -> !s.isEmpty())
.mapToInt(s -> s.split("\\s+").length)
.max()
.orElse(0);
@Holger提出的最新答案:
Arrays.stream(str.split("\\s*+(?:[.!?]\\s*+)+"))
.mapToInt(s -> s.split("\\s+").length)
.max()
.orElse(0);
还有另一种实用的样式方法(只是为了好玩)。我怀疑您是否需要它:)
Stream.of(str)
.map(splittingBy("\\s*+(?:[.!?]\\s*+)+"))
.flatMap(Arrays::stream)
.map(splittingBy("\\s+"))
.mapToInt(arr -> arr.length)
.max()
.orElse(0);
...
static Function<String, String[]> splittingBy(String regex) {
return str -> str.split(regex);
}
答案 3 :(得分:1)
您快到了。您无需将空格分开两次:您只需映射到词组中的单词数,然后使用IntStream.max
。
用" "
分隔是不够的,因为您可能有多个连续的空格(例如您的示例...Forget CVs...
),因此可以使用\\s+
分隔一个或多个空白字符。
return Arrays.stream(S.split("[.!?]")) // split into sentences
.map(String::trim)
.filter(s -> !s.isEmpty()) // get rid of empty sentences
.mapToInt(s -> s.split("\\s+").length) // map to number of words in each sentence
.max() // get the max (OptionalInt)
.orElse(0); // if there are no sentences, the result is zero