Надо подcчитать количество определенных слов (ИТ) и (ИТ-Х) в введенной строке

Рейтинг: -4Ответов: 1Опубликовано: 03.05.2023
import java.util.Scanner;
    
public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.print("Введите строку: ");
        String inputString = scanner.nextLine().replaceAll("!", "");
        int countIT = 0;
        int countIT-X = 0;
        int index = inputString.indexOf("ИТ");
        while (index != -1) {
            countIT++;
            index = inputString.indexOf("ИТ", index + 1);
        }
        index = inputString.indexOf("ИТ-х");
        while (index != -1) {
            countIT-X++;
            index = inputString.indexOf("ИТ-х", index + 1);
        }
        System.out.println("Количество упоминаний ИТ: " + countIT);
        System.out.println("Количество упоминаний ИТ-х: " + countIT-X);
    }
}

Ответы

▲ 2

Первая проблема представленного кода: ошибка компиляции, так как название переменной countIT-X содержит недопустимый символ '-', её просто исправить, заменив название переменной на countITX.

Вторая проблема в том, что одно искомое слово "ИТ" является префиксом второго искомого слова "ИТ-х", и поэтому использование простого поиска индекса для подстроки String::indexOf не совсем подходит, так как при подсчёте количество вхождений "ИТ" будет также учитывать и вхождения "ИТ-х".
Также здесь будут учитываться не отдельные слова, а любые подстроки, то есть, для строки типа "ИТИТ-х" значения счётчиков будут countIT: 2, countITX: 1, что нельзя считать правильным результатом.

Для корректного подсчёта слов следует разбить исходную строку на слова по пробельным символам и символам пунктуации, а затем вычисляя частоты слов (с использованием мапы или отдельных счётчиков).

Вариант с использованием мапы и метода Map::merge для вычисления частоты:

  • создаётся мапа частот искомых слов и заполняется нулями
  • исходная строка разбивается на слова при помощи String::split, где параметром является регулярное выражение "[.,;!?\\s]+", то есть, разделителями слов являются основные знаки препинания и пробельные символы \s.
  • для каждого найденного искомого слова инкрементируется значение частоты
public static void countWords(String str, String ... words) {
    Map<String, Integer> countMap = new LinkedHashMap<>();
    for (String w : words) countMap.put(w, 0);
    
    for (String word : str.split("[.,;!?\\s]+")) {
        if (countMap.containsKey(word)) {
            countMap.merge(word, 1, Integer::sum);
        }
    }
    
    countMap.forEach((k, v) -> System.out.printf("Количество упоминаний '%s': %d%n", k, v));
}

Тест:

countWords("ИТ-ц ИТ-х ИТ-х! ит ит-х; ИТИТ-х! ИТ спИТ", "ИТ", "ИТ-х");
Количество упоминаний 'ИТ': 1
Количество упоминаний 'ИТ-х': 2

Более "жёсткое" решение со счётчиками для заранее определённых строк:

public static void countSimple(String str) {
    int countIT = 0;
    int countITX = 0;
    for (String word : str.split("[.,;!?\\s]+")) {
        switch (word) {
            case "ИТ": countIT++; break;
            case "ИТ-х": countITX++; break;
        }
    }
    
    System.out.println("Количество упоминаний ИТ: " + countIT);
    System.out.println("Количество упоминаний ИТ-х: " + countITX);
}

Тест (искомые строки не передаются как параметр):

countSimple("ИТ-ц ИТ-х ИТ-х! ит ит-х; ИТИТ-х! ИТ спИТ?");