【问题标题】:Sort multidimensional array/slice对多维数组/切片进行排序
【发布时间】:2016-02-20 05:53:30
【问题描述】:

我在 Go 中创建了一个多维数组(切片),如下所示:

var distancematrix [5][5]int

所以它是一个 5*5 的数组/切片。 现在我将值插入到这个切片中,以便在某个点:

distancematrix :  [[0 154 12 35 138] [0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0]]

现在,我想按升序对这个数组进行排序,例如:

sorteddistancematrix :  [[0 12 35  138 154] [0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0]]

我试过sort.Ints(distancematrix[0]),但它抛出一个错误说:

cannot use distancematrix[0] (type [5]int) as type []int in argument to sort.Ints

基本上,我想获取数组中最小的非零值。 我怎样才能对这个数组进行排序以实现这一点?

【问题讨论】:

  • 您在整个问题中混合了术语数组和切片。我建议阅读this article 以获得一些澄清。
  • 获取最小的非零值不需要对数组进行排序,实际上会比较浪费。

标签: arrays sorting multidimensional-array go slice


【解决方案1】:

要获得最小的非零元素,您不需要对其进行排序。与仅获取最小的非零元素相比,对数组或切片进行排序是一项相对昂贵的操作。

通常要获得最小的非零元素,只需遍历这些值,然后寻找最适合您的值。如果您找到更好的(在您的示例中是较小的非零),请保留并继续。

示例实现:

func smallestNonZero(s []int) (n int) {
    for _, v := range s {
        if v != 0 && (v < n || n == 0) {
            n = v
        }
    }
    return
}

注意:当且仅当传递的 slice 不包含任何非零元素(即,它要么充满 0s 或者它是空的,要么它是nil)。如果切片(也)包含负数,此函数也可以正常工作。

如果你有一个数组而不是一个切片,只需对数组进行切片(这会产生一个切片),这样你就可以将它传递给上面的函数。

使用它:

fmt.Println(smallestNonZero([]int{5, 3, 1, 4}))
fmt.Println(smallestNonZero([]int{0, 3, 5, 8, 0, 2, 9}))
arr := [5]int{0, 154, 12, 35, 138}
fmt.Println(smallestNonZero(arr[:]))

输出(在Go Playground 上试试):

1
2
12

【讨论】:

  • +1 的关键点:1. 不需要对数组进行排序即可找到最小元素,以及 2. 对数组/切片进行排序通常比一个更昂贵的操作通过搜索。
  • 非常感谢 icza :) 这解决了我的问题。另外,你能告诉我如何获得最小正数的索引吗?就像我试过这个:func minimumNonZeroIndex(s []int) (n int) { var i int for i, v := range s { if v > 0 && (v
  • @fnaticRCggwp 如果你使用for range,你不应该增加循环变量i,因为它是自动/内部增加的。只需从答案中复制我的代码即可。
  • @ICZA 我需要最小正数的索引。如何使用 FOR LOOP 获得它?
【解决方案2】:

The Go Programming Language Specification

Slice expressions

切片表达式从字符串、数组、 指向数组或切片的指针。有两种变体:一种简单的形式 指定下限和上限,以及还指定 受限于容量。

简单的切片表达式

对于字符串、数组、指向数组的指针或切片 a,主 表达

a[low : high]

构造一个子字符串或切片。指数低和高选择哪个 操作数 a 的元素出现在结果中。结果有索引 从 0 开始,长度等于高 - 低。切片数组后 一个

a := [5]int{1, 2, 3, 4, 5}
s := a[1:4]

切片 s 具有 []int 类型、长度 3、容量 4 和元素

s[0] == 2
s[1] == 3
s[2] == 4

为方便起见,可以省略任何索引。缺失的低点 索引默认为零;缺少的高索引默认为 切片操作数:

a[2:]  // same as a[2 : len(a)]
a[:3]  // same as a[0 : 3]
a[:]   // same as a[0 : len(a)]

如果 a 是指向数组的指针,则 a[low : high] 是 (*a)[low :高]。

要将类型 [5]int 转换为类型 []int,请对数组进行切片。例如,

package main

import "sort"

func main() {
    var distancematrix [5][5]int
    sort.Ints(distancematrix[0][:])
}

【讨论】:

    【解决方案3】:

    var distancematrix [5][5]int,将创建 5 * 5 int 的多维数组切片。当您尝试访问 distancematrix[0] 时,它会返回 [5]int 类型的 int 数组切片。 sort.Ints 需要类型 []int。

    下面我声明了 [][] 类型的距离矩阵,因此距离矩阵 [0] 返回 []int 类型的切片数组。

    package main
    
    import (
        "fmt"
        "sort"
    )
    
    func main() {
        distancematrix := [][]int{{0, 154, 12, 35, 138}, {0, 0, 0, 0, 0}}
        sort.Ints(distancematrix[0])
        fmt.Println(distancematrix[0])
    }
    

    【讨论】:

      猜你喜欢
      • 2013-06-21
      • 2018-12-05
      • 2010-10-13
      • 1970-01-01
      • 2015-10-15
      • 2021-02-06
      • 1970-01-01
      相关资源
      最近更新 更多