Что такое метод словарь?
Словарь это структура “ключ -> значение”.
В PHP это обычный ассоциативный массив:
- ключ: строка или число (но числа часто становятся строками, если ты сам приводишь)
- значение: что угодно (bool, int, массив, объект)
Идея: по ключу можно проверять/доставать очень быстро (в среднем O(1)).
Зачем он нужен
Чтобы не делать “поиск внутри массива” каждый раз.
Потому что поиск через цикл обычно O(n).
А если ты делаешь это внутри другого цикла, привет O(n^2).
Словарь часто превращает задачу из “долго и больно” в “один проход”.
Два базовых паттерна
- Set (множество): “видел/не видел”. Тут значение не важно, обычно true.
Пример: убрать дубликаты / проверить дубликаты.
Идея: ключи это значения. Если ключ уже есть, значит повтор.
function uniqueValues(array $arr): array {
$seen = [];
$result = [];
foreach ($arr as $x) {
$key = (string)$x; // ключ в словаре
if (isset($seen[$key])) {
continue; // уже было, пропускаем
}
$seen[$key] = true; // помечаем
$result[] = $x; // сохраняем в результат
}
return $result;
}
print_r(uniqueValues([5, 2, 2, 9, 5, 1]));
// [5, 2, 9, 1]
Что тут важно:
$seenэто “множество”isset($seen[$key])это проверка “я это уже видел?”- порядок сохраняется (потому что мы складываем в
$resultпо ходу)
2. Counter (счетчик): “сколько раз встречалось”. Тут значение – число.
function countFreq(array $arr): array {
$count = [];
foreach ($arr as $x) {
$key = (string)$x;
$count[$key] = ($count[$key] ?? 0) + 1;
}
return $count;
}
print_r(countFreq([2, 2, 3, 10, 10, 10]));
// ['2' => 2, '3' => 1, '10' => 3]
Фишка строки:
($count[$key] ?? 0) + 1
- если ключа нет, берем 0
- иначе берем текущее значение
- плюс 1
Типовые задачи, которые решаются словарем
- Two Sum (пара с суммой) за O(n)
- Частоты слов/чисел (самое частое)
- Дубликаты
- Пересечение массивов
- Разница множеств
- Анаграммы (считаем буквы)
Задача: найти элементы, которые есть во всех массивах.
Правильная логика:
- для каждого массива считаем уникальные элементы (чтоб дубли внутри массива не ломали счетчик)
- увеличиваем счетчик “в скольких массивах встретилось число”
- в конце берем те, у кого счетчик == кол-во массивов
<?php
// Пересечение всех массивов: вернуть числа, которые есть в КАЖДОМ массиве (без дублей)
function intersectionAll(array $arrays): array {
if (empty($arrays)) return [];
$dict = []; // число => сколько массивов его содержат
$total = count($arrays);
foreach ($arrays as $arr) {
// защита от дублей внутри одного массива
$seenInThisArray = [];
foreach ($arr as $x) {
$key = (string)$x;
if (isset($seenInThisArray[$key])) continue;
$seenInThisArray[$key] = true;
$dict[$key] = ($dict[$key] ?? 0) + 1;
}
}
$result = [];
foreach ($dict as $key => $count) {
if ($count === $total) {
$result[] = (int)$key; // если нужны числа
}
}
return $result;
}
// Пример вызова:
$arrays = [
[1, 2, 2, 3, 10],
[2, 2, 3, 4, 10, 10],
[0, 2, 3, 5, 10],
];
print_r(intersectionAll($arrays));
// Ожидаемо: Array ( [0] => 2 [1] => 3 [2] => 10 )
// Еще пример:
$arrays2 = [
[7, 7, 8, 9],
[6, 7, 8],
[7, 8, 10],
];
print_r(intersectionAll($arrays2));
// Ожидаемо: Array ( [0] => 7 [1] => 8 )
Такой же подход использовал тут https://syntaxsteps.com/guide/php-zadacha-analiz-teksta.
