我编写了一个程序,如果该单词与列表中的单词匹配,我会在计数器中添加+1
例如,如果我有单词 [OK, NICE],并且我正在查看一个单词(该句子是用空格分隔的)。
在拆分中,我不想添加逗号和点的选项,我现在只想要这样的空格
private static int contWords(String line, List<String> list) {
String[] words= line.split(" ");
int cont = 0;
for (int i = 0; i < words.length; i++) {
if (list.contains(words[i].toUpperCase())) {
cont++;
}
}
return cont;
}
这将是一个不会为计数器添加 +1 的单词的示例,而应该
确定=真
OKEY=假
不错。 =假
很好,=假
最佳答案
问题
这是您要解决的问题:
- 获取目标词列表
- 一句话
- 统计目标词在句子单词中出现的次数
假设您在句子中查找“OK”和“NICE”,并且您的句子是“This is ok, Nice work!”,则出现次数应为 2。
选项
您有几个选择,我将使用 Streams
向您展示方法。
解决方案
private static int countWords(String sentence, List<String> targets) {
String[] words = sentence.split(" ");
return (int) Stream.of(words)
.map(String::toUpperCase)
.filter(word -> targets.stream().anyMatch(word::contains))
.count();
}
它是如何工作的?
首先,你接受一个句子,然后将其分割成一个数组(你已经这样做了)
然后,我们获取数组,然后使用 map
将每个单词映射为其大写形式。这意味着现在每个单词都将全部大写。
然后,使用filter
,我们仅将存在的单词作为子字符串保留在target
列表中。
然后,我们只返回计数。
更深入吗?
我可以更详细地了解这句话的含义:
.filter(word -> targets.stream().anyMatch(word::contains))
word -> ...
是一个函数,它接受一个 word
并输出一个 boolean
值。这很有用,因为对于每个单词,我们想知道它是否是目标的子字符串。
然后,该函数将计算 targets.stream().anyMatch(word::contains)
,它会遍历目标流,并告诉我们其中是否有任何单词包含(作为substring)我们正在过滤的单词。
忍者编辑:
在你原来的问题中,如果句子是“这很好,干得好!”目标列表是["OK", "OKEY"]
,它会返回 2。
如果这是您想要的行为,您可以将该方法更改为:
private static int countWords(String sentence, List<String> targets) {
String[] words = sentence.split(" ");
return Stream.of(words)
.map(String::toUpperCase)
.map(word -> targets.stream().filter(word::contains).count())
.reduce(0L, Long::sum)
.intValue();
}
NINJA-IER 编辑:
根据评论中提出的其他问题,您可以通过执行以下操作将所有匹配的单词替换为“***”
:
private static String replaceWordsWithAsterisks(String sentence, List<String> targets) {
String[] words = sentence.split(" ");
List<String> processedWords = Stream.of(words)
.map(word -> targets.stream().anyMatch(word.toUpperCase()::contains) ? "***" : word)
.collect(Collectors.toList());
return String.join(" ", processedWords);
}
关于java - 为什么 List.contain 不匹配子字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56711254/