Почему List.contain не соответствует подстрокам? - PullRequest
1 голос
/ 22 июня 2019

У меня есть программа, в которой я добавляю +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 к счетчику и должны

OK = true

OKEY = false

NICE. = ложь

Ницца, = ложь

1 Ответ

2 голосов
/ 22 июня 2019

Проблема

Вот проблема, которую вы пытаетесь решить:

  • Возьмите список целевых слов
  • Предложение
  • Подсчитайте количество вхождений целевых слов в словах предложения

Предположим, вы ищете «OK» и «NICE» в вашем предложении, а ваше предложение «Это нормально, хорошая работа»! ", значения должны быть 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), который проходит через целевой поток и сообщает нам, если таковые имеются.из слов в нем содержится (как подстрока) наше слово, которое мы фильтруем.

РЕДАКТИРОВАТЬ НИНДЗЯ:

В вашем первоначальном вопросе, если предложение было «Это хорошо, хорошая работа!"и список целей был ["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 EDIT:

На основании другого вопроса, предложенного в комментариях, вы можете заменить все совпадающие слова на "***", выполнив следующее:

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);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...