Проверьте, содержит ли срез строки определенное значение в Go
Каков наилучший способ проверить, находится ли определенное значение в строчном фрагменте? Я бы использовал Set на других языках, но Go не имеет его.
Моя лучшая попытка - это пока:
package main
import "fmt"
func main() {
list := []string{"a", "b", "x"}
fmt.Println(isValueInList("b", list))
fmt.Println(isValueInList("z", list))
}
func isValueInList(value string, list []string) bool {
for _, v := range list {
if v == value {
return true
}
}
return false
}
http://play.golang.org/p/gkwMz5j09n
Это решение должно быть хорошо для небольших фрагментов, но что делать для срезов со многими элементами?
Ответы
Ответ 1
Если у вас есть фрагмент строк в произвольном порядке, поиск значения в срезе требует O (n) времени. Это относится ко всем языкам.
Если вы собираетесь выполнять поиск снова и снова, вы можете использовать другие структуры данных для ускорения поиска. Однако для построения этих структур требуется не менее O (n) времени. Таким образом, вы получите преимущества только в том случае, если вы выполняете поиск с использованием структуры данных более одного раза.
Например, вы можете загрузить свои строки в карту. Тогда для поиска потребуется время O (1). Вставки также принимают время O (1), заставляя начальную сборку взять время O (n):
set := make(map[string]bool)
for _, v := range list {
set[v] = true
}
fmt.Println(set["b"])
Вы также можете отсортировать фрагмент строки, а затем выполнить двоичный поиск. Бинарные запросы происходят в O (log (n)) времени. Здание может принимать время O (n * log (n)).
sort.Strings(list)
i := sort.SearchStrings(list, "b")
fmt.Println(i < len(list) && list[i] == "b")
Хотя теоретически с учетом бесконечного числа значений, карта быстрее, на практике очень вероятно, что поиск отсортированного списка будет быстрее. Вам нужно сравнить его самостоятельно.
Ответ 2
Для замены наборов вы можете использовать map[string]whatever
. Это не будет легче, чем вы можете себе представить (там указатель на значение, которое вам не нужно), но, кроме написания собственной хеш-таблицы, он наиболее эффективен и довольно оптимизирован по мере его создания.
set := make(map[string]uint8)
Чтобы поставить элемент:
set[item]=1
Чтобы проверить, присутствует ли элемент:
_, ok = set[item]
Это обычная идиома в Go. Если ok истинно, тогда элемент присутствовал. Если ok имеет значение false, элемент отсутствует.
Ответ 3
Вы можете использовать карту и иметь значение, например. bool
m := map[string] bool {"a":true, "b":true, "x":true}
if m["a"] { // will be false if "a" is not in the map
//it was in the map
}
Также есть sort, чтобы вы могли сортировать и бинарно искать свои фрагменты