← Назад к вопросам

Найти дублирующиеся символы в строке

1.0 Junior🔥 181 комментариев
#Коллекции#Основы Java

Условие

Напишите Java-программу для нахождения дублирующихся символов в строке и подсчёта их количества.

Пример

Входные данные: "Better Butter"

Выходные данные:

t: 4
e: 3
r: 2
B: 2

Требования

  • Используйте HashMap или другую подходящую структуру данных
  • Выводите только символы, которые встречаются более одного раза
  • Учитывайте регистр (B и b - разные символы)

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Подход

Проходим по строке, подсчитываем частоту каждого символа с помощью HashMap. Затем фильтруем результат, оставляя только символы с частотой больше 1. Выводим в порядке убывания частоты.

Решение

import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
import java.util.stream.Collectors;

public class DuplicateCharacterFinder {
    
    /**
     * Находит дублирующиеся символы в строке.
     * Возвращает Map, отсортированную по убыванию частоты.
     * 
     * @param str строка для анализа
     * @return Map с символами и их частотой (только дублирующиеся)
     */
    public static Map<Character, Integer> findDuplicates(String str) {
        if (str == null || str.isEmpty()) {
            return new HashMap<>();
        }
        
        // Шаг 1: Подсчитываем частоту каждого символа
        Map<Character, Integer> charCount = new HashMap<>();
        
        for (char c : str.toCharArray()) {
            charCount.put(c, charCount.getOrDefault(c, 0) + 1);
        }
        
        // Шаг 2: Фильтруем, оставляя только дублирующиеся символы
        Map<Character, Integer> duplicates = charCount.entrySet()
            .stream()
            .filter(e -> e.getValue() > 1)
            .sorted((a, b) -> b.getValue().compareTo(a.getValue()))  // Сортируем по убыванию частоты
            .collect(Collectors.toMap(
                Map.Entry::getKey,
                Map.Entry::getValue,
                (e1, e2) -> e1,
                LinkedHashMap::new  // Сохраняем порядок
            ));
        
        return duplicates;
    }
    
    /**
     * Альтернативная реализация с явной сортировкой (более читаемая).
     */
    public static void printDuplicates(String str) {
        if (str == null || str.isEmpty()) {
            System.out.println("Строка пустая или null");
            return;
        }
        
        // Подсчитываем частоту символов
        Map<Character, Integer> charCount = new HashMap<>();
        
        for (char c : str.toCharArray()) {
            charCount.put(c, charCount.getOrDefault(c, 0) + 1);
        }
        
        // Сортируем по убыванию частоты и выводим
        charCount.entrySet()
            .stream()
            .filter(e -> e.getValue() > 1)
            .sorted((a, b) -> b.getValue().compareTo(a.getValue()))
            .forEach(e -> System.out.println(e.getKey() + ": " + e.getValue()));
    }
    
    public static void main(String[] args) {
        System.out.println("=== Примеры поиска дублирующихся символов ===");
        
        // Пример 1: Из задания
        String test1 = "Better Butter";
        System.out.println("\nСтрока: \"" + test1 + "\"");
        printDuplicates(test1);
        // Ожидаемый результат:
        // t: 4
        // e: 3
        // r: 2
        // B: 2 (пробел не входит в дублирующиеся)
        // (пробел: 1, один раз, не дублируется)
        
        // Пример 2: С цифрами и спецсимволами
        String test2 = "aabbcc123123";
        System.out.println("\nСтрока: \"" + test2 + "\"");
        printDuplicates(test2);
        // a: 2, b: 2, c: 2, 1: 2, 2: 2, 3: 2
        
        // Пример 3: Без дубликатов
        String test3 = "abcdef";
        System.out.println("\nСтрока: \"" + test3 + "\"");
        Map<Character, Integer> result3 = findDuplicates(test3);
        System.out.println(result3.isEmpty() ? "Нет дублирующихся символов" : result3);
        
        // Пример 4: Пустая строка
        String test4 = "";
        System.out.println("\nСтрока: \"" + test4 + "\"");
        System.out.println(findDuplicates(test4));
        
        // Пример 5: Регистр-чувствительность
        String test5 = "AaAa";
        System.out.println("\nСтрока: \"" + test5 + "\"");
        printDuplicates(test5);
        // A: 2, a: 2 (разные символы)
    }
}

import java.util.LinkedHashMap;

Сложность

  • Временная сложность: O(n log n), где n — количество символов. O(n) для подсчёта, O(k log k) для сортировки (k — количество уникальных символов).
  • Пространственная сложность: O(k), где k — количество уникальных символов (максимум 256 для ASCII).

Примеры и тест-кейсы

  1. Из задания: "Better Butter" → t:4, e:3, r:2, B:2
  2. С повторениями: "aabbcc" → a:2, b:2, c:2
  3. Без дубликатов: "abcdef" → пусто (нет дублирующихся)
  4. С пробелами: "a a b b" → a:2, b:2 (пробел: 3, входит)
  5. Регистр чувствителен: "AaBbAa" → A:2, a:2, B:1, b:1

Edge cases и типичные ошибки

  1. Пустая строка: Возвращаем пустую HashMap.
  2. Null значение: Проверяем перед началом работы.
  3. Пробелы: Они считаются как обычные символы (встречаются в задаче).
  4. Регистр: Задача требует учитывать регистр (B и b — разные).
  5. Сортировка: Используем sorted() для порядка по убыванию частоты для лучшей читаемости результата.

Решение демонстрирует владение HashMap, Stream API и обработкой символов.

Найти дублирующиеся символы в строке | PrepBro