Существует множество ситуаций, когда вам нужно выбрать произвольную запись на карте, содержащую тысячи или миллионы элементов.Например, отображение случайной цитаты, или определения, или обратной связи с клиентом.Для ясности, в оставшейся части этого поста я буду предполагать, что я имею дело со словарной картой, где ключ String - это слово, а значение String - его определение.
Подход к этому грубой силыпроблемы могут быть примерно такими.
// Bruteforce approach
x = new integer between 0 and the number of entries in the map
iterate x times
return the element
Мне кажется, что использование подхода грубой силы не только медленное и трудоемкое, но и глупое.
Зачем мне повторять более тысячиэлементов, чтобы найти что-то, что я не особо ищу?
Единственный способ избежать грубой силы и иметь O (1) случайный поиск - это иметь целое число в качестве ключа карты, потому чтодве точки:
- Единственный случайный объект, который мы можем получить, является целым числом
- Единственный способ поиска O (1)на карте, это знать ключ.
Но так как вы можете иметь только один ключ, если вы поставите целое число в качестве ключа, то вы не можете иметь O (1)поиск определения данного слова, который был точкойиспользуя Map во-первых.
Я нашел способ сделать это - объявить вторую карту, «привязывающую» карту, которая просто связывает каждый ключ словаря с целым числом.
Таким образом, в итоге вы получите две карты:
- Словарь, в котором у вас есть слова в качестве ключей и определения в качестве значений
- у вас есть целые числа в качестве ключей и слова в качестве значений
Итак, если вы хотите получить определение данного слова, вы делаете:
dictionary.get("hello");
И если вы хотите получитьслучайное слово, которое вы просто делаете:
dictionary.get(bindingMap.get(myRandomNumber));
Плюсы:
- Это позволяет O (1) поиск И случайный доступ
Минусы:
- Сложность пространства - это O (2n) вместо O (n) ... Что все еще равно O (n) ...
Что вы думаете об этом методе?Видите ли вы лучший способ сделать это?