为了账号安全,请及时绑定邮箱和手机立即绑定

如何在 golang 中对定长数组进行排序?

如何在 golang 中对定长数组进行排序?

Go
素胚勾勒不出你 2023-04-10 10:13:08
我有以下多元数组:x := [2][3]int{    {3, 2, 1},    {3, 2, 1},}行和列都是固定大小的。我正在尝试检查行是否已排序,并且我理解排序函数需要大小未知的数组。我怎样才能要求 go 将已知大小的固定项目视为大小未知的项目?var allTrue bool = truefor i := range x {  t := sort.Ints(x[i]) == []int{1, 2, 3}  allTrue = allTrue && t}我得到:./main.go:xx:yy: sort.Ints(x[i]) used as value./main.go:xx:yy: cannot use x[i] (type [3]int) as type []int in argument to sort.Ints我是否正确阅读此错误消息?
查看完整描述

3 回答

?
一只斗牛犬

TA贡献1784条经验 获得超2个赞

解决代码问题

如上所述,切片与数组具有不同的类型,因此您不能在需要[N]T某些类型的地方N使用某些类型的东西。T[]T

sort.Ints就地对整数切片进行排序——它具有类型签名func Ints(a []int)。您的调用在 indexsort.Ints(x[i])索引数组 ,这将返回一个 type 的数组。这与 sort 函数不兼容,会导致您观察到的编译时错误。xi[3]int

要从数组中获取切片,可以使用切片表达式。这样的表达式允许使用数组、切片和一些其他类型来构造新的切片。

切片表达式以以下形式给出,a[low : high]其中lowhigh是可选的整数,提供到支持数组或切片的索引,这些索引指定要在新切片中返回的范围。上面的语言规范链接有更多详细信息,我建议您阅读;可以说a[:]一些数组或切片的最简单切片表达式a是语法糖来表示a[0:len(a)-1],即将数组/切片转换为相同长度的切片。

[]int使用这个技巧,通过切片从多维数组中获取类型的切片x[i][:]

  • x[i][3]int像以前一样返回类型为 的数组

  • 对返回的数组进行切片会返回类型为 的切片[]int,该切片与 兼容sort.Ints


sort.Ints不返回值,切片不可比较

即使您用代码解决了这些问题,以下行仍然存在两个问题:

t := sort.Ints(x[i]) == []int{1, 2, 3}
  1. sort.Ints就地排序;它不返回值,因此相等性测试没有意义。

  2. sort.Ints对不可比较的切片进行操作。不可能调用A == Bwhere either Aor Bis a slice,除非 either AorB是特殊标识符nil。这是语言规范中涵盖的一个微妙点。(另外:阅读那一页,你会注意到数组可比较的。)

由于您无法使用相等运算符直接比较切片==,因此验证切片的逐元素相等性需要:

  • 切片具有相同的长度(不同的长度意味着一个切片比另一个具有更多的元素)

  • 一个切片的每个索引处的元素与其他切片相同。

(我忽略了一个切片可能与另一个切片具有不同容量的事实,因为我们只关心元素方面的相等性。)

这可以通过遍历其中一个切片并验证每个索引处的元素对应于另一个切片中的相同索引来验证。此示例代码提供了一个示例:

package main


import (

    "fmt"

)


func CheckEquality(a, b []int) bool {

    // Slices of dissimilar length are not equal

    if len(a) != len(b) {

        return false

    }


    for i, el := range a {

        if b[i] != el {

            return false

        }

    }


    return true

}


func main() {

    var mySlice = []int{1, 2, 3, 4, 5}

    var mySlice2 = []int{1, 2, 3, 4, 5}   // same as mySlice

    var otherSlice = []int{5, 6, 7, 8, 9} // dissimilar slice

    var longSlice = []int{1, 2, 3, 4, 5, 6, 7, 8, 9}


    fmt.Println(CheckEquality(mySlice, mySlice2))   // Expect true

    fmt.Println(CheckEquality(mySlice, otherSlice)) // Expect false

    fmt.Println(CheckEquality(mySlice, longSlice))  // Expect false

}


查看完整回答
反对 回复 2023-04-10
?
红颜莎娜

TA贡献1842条经验 获得超12个赞

您必须先使用[:]运算符对数组进行切片,然后才能将其与sort包一起使用。

此外,您可以检查切片的排序是否比排序更有效,使用sort.IntsAreSorted([]int), 就像这样。

var allTrue bool = true

for i := range x {

    if !sort.IntsAreSorted(x[i][:]) {

        allTrue = false

        break

    }

}


查看完整回答
反对 回复 2023-04-10
?
慕仙森

TA贡献1827条经验 获得超7个赞

您可以使用运算符从数组中获取切片[:],例如:


arr := [3]int{1, 2, 3}

slc := arr[:] // []int{1, 2, 3}, backed by arr

因此,您可以使用以下sort.Ints(...)功能:


sort.Ints(x[0][:])

sort.Ints(x[1][:])

// Now both elements of "x" are sorted.


查看完整回答
反对 回复 2023-04-10
  • 3 回答
  • 0 关注
  • 115 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信