假设您有两个用例:
a := [] int {2, 2, 3, 4}
i := sort.Search(len(a), func(pos int) bool { return a[pos] == 2})
fmt.Printf("%v -> %v \n", a, i)
b := [] int {1, 2, 2, 3, 4}
j := sort.Search(len(b), func(pos int) bool { return b[pos] == 2})
fmt.Printf("%v -> %v \n", b, j)
答案是:
[2 2 3 4] -> 4
[1 2 2 3 4] -> 1
我想在两种情况下都必须是1
,不是吗?有谁知道为什么?
答案 0 :(得分:4)
sort.Search()
返回i
[0, n)
为f(i)
的{{1}}中的最小索引true
。
由于切片索引从0开始,您应该期望第一个返回0
,第二个返回1
。它(貌似)适用于第二种。
从文档引用:
...假设在范围[0,n)上,
f(i) == true
暗示f(i+1) == true
。也就是说,搜索要求f
为false
表示输入范围[0,n]的某些(可能为空)前缀,然后true
为(可能为空)余数;搜索返回第一个true
索引。如果没有此类索引,搜索将返回n
。
您的功能不符合sort.Search()
期望的标准。你的功能不是要判断指定索引处的元素是否是你要查找的元素,而是告诉:
true
)false
)。(如果您只知道它们何时相等,则无法执行二进制搜索,但是当它们更大或更小时则不能执行。)
因此,只需使用>=
比较代替==
。正确用法:
a := []int{2, 2, 3, 4}
i := sort.Search(len(a), func(pos int) bool { return a[pos] >= 2 })
fmt.Printf("%v -> %v \n", a, i)
b := []int{1, 2, 2, 3, 4}
j := sort.Search(len(b), func(pos int) bool { return b[pos] >= 2 })
fmt.Printf("%v -> %v \n", b, j)
输出(在 Go Playground 上试试):
[2 2 3 4] -> 0
[1 2 2 3 4] -> 1
注意:也来自doc:
例如,给定按升序排序的切片数据,调用
Search(len(data), func(i int) bool { return data[i] >= 23 })
返回最小的索引
i
,使data[i] >= 23
。如果调用者想要查找切片中是否23
,则必须单独测试data[i] == 23
。
sort.SearchInts()
如果您想在int
切片(int
)中搜索[]int
值,只需使用sort.SearchInts()
:
a := []int{2, 2, 3, 4}
i := sort.SearchInts(a, 2)
fmt.Printf("%v -> %v \n", a, i)
b := []int{1, 2, 2, 3, 4}
j := sort.SearchInts(b, 2)
fmt.Printf("%v -> %v \n", b, j)
输出(在 Go Playground 上试试):
[2 2 3 4] -> 0
[1 2 2 3 4] -> 1