sort.SearchInts的工作方式很奇怪,或者我漏掉了什么东西。

huangapple go评论84阅读模式
英文:

sort.SearchInts works strangely or I'm missing something

问题

考虑以下示例:

package main

import (
    "fmt"
    "sort"
)

func main() {
    var n int
    var a sort.IntSlice
    a = append(a, 23)    
    a = append(a, 3)
    a = append(a, 10)
    sort.Sort(a)    
    fmt.Println(a)
    n = sort.SearchInts(a, 1)
    fmt.Println(n)
    n = sort.SearchInts(a, 3)
    fmt.Println(n)
}

http://play.golang.org/p/wo4r43Zghv

结果是:

[3 10 23]
0
0

当第一个元素和不存在的元素都返回索引0时,我怎么知道数字是否存在于切片中?

更新
请注意,索引也可能大于切片的长度,因此在切片中查找元素的正确方法是:

num := 1
n = sort.SearchInts(a, num) 
if n < len(a) && a[n] == num {
  // 找到了
}
英文:

Consider the following example:

package main

import (
	&quot;fmt&quot;
	&quot;sort&quot;
)

func main() {
	var n int
	var a sort.IntSlice
	a = append(a, 23)	
	a = append(a, 3)
	a = append(a, 10)
	sort.Sort(a)	
	fmt.Println(a)
	n = sort.SearchInts(a, 1)
	fmt.Println(n)
	n = sort.SearchInts(a, 3)
	fmt.Println(n)
}

http://play.golang.org/p/wo4r43Zghv

And the result is:

[3 10 23]
0
0

How am I supposed to know if the number is present in the slice or not, when both the first element and the nonexistent element return 0 as index?

Update
Note that the index can also be greater than the length of the slice so the proper way to find if an element is present in the slice is:

num := 1
n = sort.SearchInts(a, num) 
if n &lt; len(a) &amp;&amp; a[n] == num {
  // found
}

答案1

得分: 3

这可能看起来是一个功能上奇怪的特性,但它已经有文档记录:

例如,给定一个按升序排序的切片数据,调用Search(len(data), func(i int) bool { return data[i] >= 23 })将返回最小的索引i,使得data[i] >= 23。

明显的解决方案也有文档记录:

如果调用者想要查找切片中是否存在23,它必须单独测试data[i] == 23。

英文:

It may seem a functionally strange feature but it's documented :

> For instance, given a slice data sorted in ascending order, the call
> Search(len(data), func(i int) bool { return data[i] >= 23 }) returns
> the smallest index i such that data[i] >= 23.

The obvious solution is also documented :

> If the caller wants to
> find whether 23 is in the slice, it must test data[i] == 23
> separately.

答案2

得分: 1

检查你正在寻找的数字是否确实存在于返回的索引位置。在sort中的二分搜索例程应该能够找到一个值可以插入的索引位置,如果它还不存在的话。

例如,在你的示例中,对切片搜索100将返回3,因为该值必须附加到切片中。

调用Search(len(data), func(i int) bool { return data[i] >= 23 })将返回最小的索引i,使得data[i] >= 23。如果调用者想要找到23是否在切片中,它必须单独测试data[i] == 23

英文:

Check whether the number you were looking for actually lives at the returned index. The binary search routines in sort are supposed to find the index where a value can be inserted if it's not already present.

E.g. a search for 100 in the slice in your example will return 3 because the value must be appended to the slice.

> the call Search(len(data), func(i int) bool { return data[i] &gt;= 23 }) returns the smallest index i such that data[i] &gt;= 23. If the caller wants to find whether 23 is in the slice, it must test data[i] == 23 separately.

答案3

得分: 1

SearchInts在一个已排序的整数切片中搜索x,并根据Search指定的规则返回索引。SearchInts使用一个函数调用Search

func(i int) bool { return a[i] >= x }

引用自Search文档:

> Search使用二分查找在[0, n)范围内找到并返回满足f(i)为true的最小索引i,假设在范围[0, n)上,
> f(i) == true意味着f(i+1) == true。也就是说,Search要求f对于输入范围[0, n)的某些(可能为空)前缀为false,
> 然后对于剩余的(可能为空)部分为true;Search返回第一个为true的索引。如果没有这样的索引,Search返回n。Search
> 仅对范围[0, n)中的i调用f(i)。

因此,基本上你将得到一个索引,该索引是你搜索的数字应该插入的位置,以使切片保持有序。

只需检查返回的索引处的切片中的数字是否与你搜索的数字相同。

英文:

SearchInts searches for x in a sorted slice of ints and returns the index as specified by Search. SearchInts calls Search with a function:

func(i int) bool { return a[i] &gt;= x }

Quoting from the Search doc:

> Search uses binary search to find and return the smallest index i in [0, n) at which f(i) is true, assuming that on the range [0, n),
> f(i) == true implies f(i+1) == true. That is, Search requires that f
> is false for some (possibly empty) prefix of the input range [0, n)
> and then true for the (possibly empty) remainder; Search returns the
> first true index. If there is no such index, Search returns n. Search
> calls f(i) only for i in the range [0, n).

So basically you'll get back an index where the number you searched for should be inserted so the slice remains sorted.

Just check if at the returned index the number in the slice is identical to the one you searched for.

答案4

得分: 1

这段代码片段来自文档:

x := 23
i := sort.Search(len(data), func(i int) bool { return data[i] >= x })
if i < len(data) && data[i] == x {
    // x 在 data[i] 处出现
} else {
    // x 不在 data 中,
    // 但 i 是它应该插入的索引位置。
}

http://golang.org/pkg/sort/#Search

所以你需要像你建议的那样检查 i < len(data) && data[i] == x

英文:

This snippet is from the documentation:

x := 23
i := sort.Search(len(data), func(i int) bool { return data[i] &gt;= x })
if i &lt; len(data) &amp;&amp; data[i] == x {
	// x is present at data[i]
} else {
	// x is not present in data,
	// but i is the index where it would be inserted.
}

http://golang.org/pkg/sort/#Search

So you have to check i &lt; len(data) &amp;&amp; data[i] == x like you suggest.

huangapple
  • 本文由 发表于 2013年1月21日 18:34:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/14436751.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定