Как в Go эффективно найти элемент в отсортированном срезе или определить позицию для вставки?

Ответ

Для эффективного поиска в отсортированном срезе в Go используется функция sort.Search(). Она реализует алгоритм бинарного поиска (сложность O(log n)) и является стандартным инструментом для таких задач.

sort.Search() находит и возвращает наименьший индекс i в диапазоне [0, n), для которого переданная функция-предикат вернет true.

Пример: Поиск позиции для вставки

package main

import (
    "fmt"
    "sort"
)

func main() {
    data := []int{10, 20, 30, 50, 60} // Срез должен быть отсортирован
    x := 45 // Значение, которое мы хотим вставить

    // Находим первый элемент, который больше или равен x
    i := sort.Search(len(data), func(i int) bool {
        return data[i] >= x
    })

    // Если i < len(data), то data[i] — это первый элемент >= x.
    // Это и есть позиция для вставки x с сохранением сортировки.
    fmt.Printf("Значение %d следует вставить по индексу %dn", x, i)
    // Вывод: Значение 45 следует вставить по индексу 3
}

Ключевые моменты:

  1. Срез должен быть отсортирован по возрастанию. В противном случае результат непредсказуем.
  2. Для стандартных типов есть готовые, более быстрые реализации: sort.SearchInts(), sort.SearchFloat64s(), sort.SearchStrings().
  3. Это не "приблизительный" или "нечеткий" поиск (fuzzy search), а поиск точной позиции в упорядоченной структуре.