Я пытаюсь решить упражнение "Прогулка lanaguage" # 1.4, которое требует от меня набора. Я могу создать тип набора, но почему язык не приходит с одним? go, появившись из google, где также возникла гуава, почему разработчики языка не захотели добавить поддержку фундаментальных структур данных? зачем заставить ваших пользователей создавать свои собственные реализации для чего-то такого базового, как набор?
golang, почему у нас нет заданной структуры данных
Ответ 1
Отчасти потому, что у Go нет дженериков (так что вам понадобится один тип набора для каждого типа или вернуться к отражению, что довольно неэффективно).
Частично, потому что, если вам нужно всего лишь "добавить/удалить отдельные элементы в набор" и "относительно экономично", вы можете получить справедливый бит, просто используя map[yourtype]bool
(и установите значение true
для любого элемента в наборе) или, для большей эффективности пространства, вы можете использовать пустую структуру как значение и использовать _, present = the_setoid[key]
чтобы проверить наличие.
Ответ 2
Одна из причин заключается в том, что легко создать набор из карты:
s := map[int]bool{5: true, 2: true}
_, ok := s[6] // check for existence
s[8] = true // add element
delete(s, 2) // remove element
союз
s_union := map[int]bool{}
for k, _ := range s1{
s_union[k] = true
}
for k, _ := range s2{
s_union[k] = true
}
пересечение
s_intersection := map[int]bool{}
for k,_ := range s1 {
if s2[k] {
s_intersection[k] = true
}
}
На самом деле не так сложно реализовать все остальные операции набора.
Ответ 3
Другая возможность - использовать битовые множества, для которых есть хотя бы один пакет, или вы можете использовать встроенный большой пакет. В этом случае вам нужно определить способ преобразования объекта в индекс.
Ответ 4
Как писал Ватине: "Поскольку у вас недостает дженериков, он должен быть частью языка, а не стандартной библиотеки. Для этого вам тогда придется загрязнять язык с помощью набора слов, объединения, пересечения, разности, подмножества...
Другая причина заключается в том, что не совсем ясно, что означает "правильная" реализация набора:
-
Существует функциональный подход:
func IsInEvenNumbers(n int) bool { if n % 2 == 0 { return true } return false }
Это набор всех четных целых чисел. Он имеет очень эффективный поиск и объединение, пересечение, разность и подмножество, которые легко могут быть выполнены с помощью функциональной композиции.
- Или вы делаете подобный подход, как показал Дали.
На карте нет этой проблемы, поскольку вы храните что-то, связанное со значением.