Golang中使用sort.SearchStrings在切片中查找元素时遇到的错误

Golang中使用sort.SearchStrings在切片中查找元素时遇到的错误 我正在使用 sort.SearchStrings 在切片中查找元素(切片按升序排序,符合 sort.SearchStrings 的要求),但得到了错误的解决方案。

package main

import ( "fmt" "sort" )

func main() {

// Slice is sorted in ascending order, as requested sort.SearchStrings

Slice := []string{"1ZzLBmxsdbKiab9qcKKutMAnNGpYnLtmc", 
"1ZzT38aAMzaCo8SsB1tV2qgPA9BsbMcc5", 
"1zZf3HNcG4vSd6LwktYGk1SkXRk65cps6",
}

fmt.Println(sort.SearchStrings(Slice, "1ZzT38aAMzaCo8SsB1tV2qgPA9BsbMcc4"))
} // Show 1. Should show 3

我期望得到 3(切片的长度,因为字符串不在切片中),但实际输出是 1。


更多关于Golang中使用sort.SearchStrings在切片中查找元素时遇到的错误的实战教程也可以访问 https://www.itying.com/category-94-b0.html

4 回复

哈哈!完全没问题,很高兴能帮上忙!

更多关于Golang中使用sort.SearchStrings在切片中查找元素时遇到的错误的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


我的天啊!!

我读了这篇文章

yourbasic.org yourbasic.org

文章缩略图

在切片/数组中使用线性或二分查找查找元素

代码示例:要检查切片或数组是否包含某个元素,你可以编写自己的线性搜索函数,或者使用提供的二分查找函数。

在"二分查找"部分让我理解错了:

"len(a) 如果没有这样的索引。"

很抱歉没有阅读文档。新手!!

谢谢

你好 Frank,

我快速阅读了 sort.SearchStrings 的文档,其中提到:

SearchStrings 在已排序的字符串切片中搜索 x,并返回 Search 指定的索引。如果 x 不存在,返回值是插入 x 的索引(可能是 len(a))。切片必须按升序排序。

pkg.go.dev

sort 包 - sort - Go 包文档

包 sort 提供了对切片和用户定义集合进行排序的基本功能。

正如你正确指出的,搜索字符串在排序集合中不存在。了解这一点后,如果你注意文档中的上述引用,当搜索字符串不存在时,返回的值是维护排序顺序时需要插入搜索字符串的索引,在你的例子中就是 1

如果你将搜索字符串改为以下内容(将 4 替换为 7):

1ZzT38aAMzaCo8SsB1tV2qgPA9BsbMcc7

SearchStrings 调用的返回值将是 2,因为需要将此值追加到排序集合中以保持排序顺序。

希望这能解释清楚。

在您的代码中,sort.SearchStrings 的行为与预期不符是因为它返回的是插入位置,而不是元素索引或切片长度。sort.SearchStrings 在排序的字符串切片中执行二分查找,返回第一个大于或等于目标字符串的索引位置。如果目标字符串大于所有元素,则返回切片长度。

在您的示例中:

  • 切片:["1ZzLBmxsdbKiab9qcKKutMAnNGpYnLtmc", "1ZzT38aAMzaCo8SsB1tV2qgPA9BsbMcc5", "1zZf3HNcG4vSd6LwktYGk1SkXRk65cps6"]
  • 目标:"1ZzT38aAMzaCo8SsB1tV2qgPA9BsbMcc4"

由于 "1ZzT38aAMzaCo8SsB1tV2qgPA9BsbMcc4" 按字典顺序小于 "1ZzT38aAMzaCo8SsB1tV2qgPA9BsbMcc5" 但大于 "1ZzLBmxsdbKiab9qcKKutMAnNGpYnLtmc"sort.SearchStrings 返回 1,表示这是目标字符串应该插入的位置。

要检查元素是否存在并获取正确索引,您需要验证返回位置上的元素是否与目标匹配:

package main

import (
    "fmt"
    "sort"
)

func main() {
    slice := []string{
        "1ZzLBmxsdbKiab9qcKKutMAnNGpYnLtmc",
        "1ZzT38aAMzaCo8SsB1tV2qgPA9BsbMcc5", 
        "1zZf3HNcG4vSd6LwktYGk1SkXRk65cps6",
    }
    
    target := "1ZzT38aAMzaCo8SsB1tV2qgPA9BsbMcc4"
    pos := sort.SearchStrings(slice, target)
    
    // 检查元素是否存在
    if pos < len(slice) && slice[pos] == target {
        fmt.Printf("元素找到,索引: %d\n", pos)
    } else {
        fmt.Printf("元素未找到,应插入位置: %d\n", pos)
        fmt.Printf("切片长度: %d\n", len(slice))
    }
}

输出:

元素未找到,应插入位置: 1
切片长度: 3

如果您需要元素不存在时返回切片长度,可以这样处理:

func findStringIndex(slice []string, target string) int {
    pos := sort.SearchStrings(slice, target)
    if pos < len(slice) && slice[pos] == target {
        return pos
    }
    return len(slice)
}

func main() {
    slice := []string{
        "1ZzLBmxsdbKiab9qcKKutMAnNGpYnLtmc",
        "1ZzT38aAMzaCo8SsB1tV2qgPA9BsbMcc5", 
        "1zZf3HNcG4vSd6LwktYGk1SkXRk65cps6",
    }
    
    target := "1ZzT38aAMzaCo8SsB1tV2qgPA9BsbMcc4"
    result := findStringIndex(slice, target)
    fmt.Println(result) // 输出: 3
}

这样就能正确返回 3 当元素不存在于切片中。

回到顶部