sort.Search runs binary search. It's only guaranteed to work when you
provide it with a function which is monotonic -- true at index i implies
true at all indices greater than i.

Your loop style search does not provide a monotonic function, whereas your
"upper" function is monotonic. However, since "lower" is also not monotonic
I'd question whether the first approach would continue to work on larger
arrays. When testing binary search algorithms, it's important to use arrays
of many varying sizes, since the edge cases often don't appear on smaller
length lists.

In any case, on a sorted list, "upper" should be the only function you need
to determine whether the needle can be found in the list. sort.Search
guarantees that the index it returns is the first index where the monotonic
function changes its value. If the needle you're looking for is in the
haystack, the value at that index will be the needle itself.

On Tue, Oct 11, 2022, 7:22 AM 'ljh' via golang-nuts <
golang-nuts@googlegroups.com> wrote:

> Hi community,
>
> I used sort.Search on a sorted slice in below code started at Line 36, and
> it worked.
>
> I also tried to call sort.Search in a loop, started at Line 53. It does
> not seem to work. How can I correct the loop version?
>
> Thanks
>
> ---
>
> package main
>
> import (
> "log"
> "sort"
> )
>
> type T struct {
> name string
> }
>
> func main() {
> log.SetFlags(log.LstdFlags | log.Llongfile)
>
> haystack := []T{
> // {name: "apple",  },
> {name: "compote", }, //dup
> {name: "orange", },
> {name: "compote", }, //dup
> }
>
> sort.Slice(haystack, func(i, j int) bool {
> if haystack[i].name < haystack[j].name {
> return true
> } else {
> return false
> }
> })
>
> for _, t := range haystack {
> log.Println("sorted", t)
> }
>
> needle := T{name: "compote"}
>
> // Style 1: ok, lower upper bounds style // Line 36
> /*
> lower := sort.Search(len(haystack), func(i int) bool {
> return haystack[i].name == needle.name
> })
>
> upper := sort.Search(len(haystack), func(i int) bool {
> return haystack[i].name > needle.name
> })
>
> if lower != len(haystack) {
> for i := lower; i != upper; i++ {
> log.Println("found", i, haystack[i])
> }
> }
> */
>
> // Style 2: error, loop style // Line 53
> for index := 0; index < len(haystack); index++ {
> ret := sort.Search(len(haystack[index:]), func(i int) bool {
> return haystack[index:][i].name == needle.name })
>
> log.Println(index, ret)
>
> if ret < len(haystack) {
> index += ret
> log.Println("found", index, haystack[index])
> }
> }
> }
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/tencent_659665C8263F2DF81643C2B86412244F3105%40qq.com
> <https://groups.google.com/d/msgid/golang-nuts/tencent_659665C8263F2DF81643C2B86412244F3105%40qq.com?utm_medium=email&utm_source=footer>
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CALJzkY_JSC9pGUTuaXdzf1Wayq8%2BQUjpq2dT%3DqsQKhCcy1Sbgg%40mail.gmail.com.

Reply via email to