Ответ
Эту задачу, известную как "нахождение разности множеств", в Go эффективнее всего решать с помощью map
для создания хеш-сета.
Алгоритм:
- Создать
map[T]struct{}
(гдеT
— тип элементов среза) для хранения элементов второго среза. Использование пустой структурыstruct{}
в качестве значения является идиоматичным, так как она не занимает памяти. - Пройтись по второму срезу (
sliceB
) и добавить все его элементы вmap
в качестве ключей. - Пройтись по первому срезу (
sliceA
) и для каждого элемента проверить, есть ли он вmap
. Если элемента вmap
нет, добавить его в результирующий срез.
Этот подход имеет сложность O(N+M), где N и M — длины срезов, что гораздо эффективнее вложенных циклов со сложностью O(N*M).
package main
import "fmt"
// difference возвращает элементы, которые есть в a, но нет в b.
func difference(a, b []int) []int {
// Создаем сет для быстрой проверки наличия элементов из b
setB := make(map[int]struct{}, len(b))
for _, item := range b {
setB[item] = struct{}{}
}
var result []int
// Проверяем каждый элемент из a
for _, item := range a {
if _, found := setB[item]; !found {
result = append(result, item)
}
}
return result
}
func main() {
sliceA := []int{1, 2, 3, 4, 5, 6}
sliceB := []int{2, 4, 7}
// Находим элементы, которые есть в sliceA, но нет в sliceB
diff := difference(sliceA, sliceB)
fmt.Println(diff) // Вывод: [1 3 5 6]
}