← Все вопросы

Как пользоваться std::unordered_map в C++? Нужна хеш-таблица для подсчёта частот

Задан 9 месяцев назад1.1к просмотров2 ответа
6

Решаю задачу на Codeforces: дан массив, надо посчитать, сколько раз встречается каждое число. В Python я бы взял словарь, а в C++ слышал про хеш-таблицу unordered_map, но не понимаю синтаксис.

Как её объявить, как добавить элемент, как проверить наличие ключа и как пройтись по всем парам? И чем она отличается от map?

2 ответа

12
✓ Принятый ответ — помог автору

std::unordered_map — это и есть хеш-таблица, прямой аналог словаря из Python. Лежит в заголовке <unordered_map>.

Полный пример для твоей задачи (подсчёт частот):

#include <iostream>
#include <unordered_map>
using namespace std;

int main() {
    int arr[] = {5, 3, 5, 2, 3, 5};
    unordered_map<int, int> cnt;

    for (int x : arr) {
        cnt[x]++;   // если ключа нет — создаётся со значением 0, потом +1
    }

    // проверка наличия ключа
    if (cnt.count(5)) {
        cout << "5 встречается " << cnt[5] << " раз\n";
    }

    // проход по всем парам ключ-значение
    for (auto& [key, value] : cnt) {
        cout << key << " -> " << value << "\n";
    }
    return 0;
}

Ключевые операции:

  • m[key] — доступ/создание элемента
  • m.count(key) — вернёт 1 если ключ есть, 0 если нет
  • m.find(key) — итератор (или m.end() если не нашлось)
  • m.erase(key) — удалить
  • m.size() — количество элементов

Отличие от map: unordered_map — хеш-таблица, доступ в среднем за O(1), но порядок ключей произвольный. map — это дерево, доступ за O(log n), зато ключи всегда отсортированы. Для подсчёта частот, где порядок не важен, unordered_map быстрее.

5

Осторожно на Codeforces: у unordered_map бывают anti-hash тесты, когда злонамеренный набор ключей превращает O(1) в O(n) из-за коллизий, и решение получает TL.

Лайфхак — задать свой хеш или просто использовать map если n небольшое. Или зарезервировать память заранее:

unordered_map<int,int> cnt;
cnt.reserve(1024);
cnt.max_load_factor(0.25);

Ваш ответ

Войдите, чтобы ответить на вопрос.
Поддержать проект