排序多维数组/切片

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

Sort multidimensional array/slice

问题

我在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

基本上,我想获取数组中最小的非零值。我该如何对这个数组进行排序以实现这一目标?

英文:

I have created a multidimensional array (slice) in Go as follows:

var distancematrix [5][5]int

So it is a 5*5 array/slice.
Now I am inserting values into this slice such that at a point:

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]]

Now, I want to sort this array in ascending order, e.g.:

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]]

I tried sort.Ints(distancematrix[0]) but it throws an error saying:

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

Basically, I want to fetch the smallest non-zero value in the array.
How can I sort this array to achieve this?

答案1

得分: 4

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

通常,要获取最小的非零元素,只需遍历值,并寻找最适合你的值。如果找到更好的值(在你的示例中是更小的非零值),则保留该值并继续。

示例实现:

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

注意: 如果传递的切片不包含任何非零元素(即,要么全是0,要么为空,要么为nil),此函数将返回0。如果切片(也)包含负数,此函数也能正常工作。

如果你有一个数组而不是切片,只需对数组进行切片(得到一个切片),然后将其传递给上述函数。

使用示例:

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
英文:

To get the smallest non-zero element, you don't need to sort it. Sorting an array or slice is relatively a costly operation - compared to just getting the smallest non-zero element.

Generally to get the smallest non-zero element, just loop over the values, and look for the value that fits you best. If you find a better one (in your example a smaller non-zero), keep that and continue.

Example implementation:

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

Note: This function will return 0 if and only if the passed slice does not contain any non-zero element (that is, it's either full of 0s or it's empty or it's nil). This function also works properly if the slice (also) contains negative numbers.

If you have an array and not a slice, simply slice the array (which results in a slice) and so you can pass it to the function above.

Using it:

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[:]))

Output (try it on the Go Playground):

1
2
12

答案2

得分: 2

《Go编程语言规范》

切片表达式

切片表达式从字符串、数组、数组指针或切片中构造子字符串或切片。有两种变体:简单形式指定下界和上界,完整形式还指定容量上界。

简单切片表达式

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

a[low : high]

构造一个子字符串或切片。下标low和high选择操作数a中出现在结果中的元素。结果的下标从0开始,长度等于high - low。在对数组a进行切片之后

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:]  // 等同于 a[2 : len(a)]
a[:3]  // 等同于 a[0 : 3]
a[:]   // 等同于 a[0 : len(a)]

如果a是一个指向数组的指针,则a[low : high]是(*a)[low : high]的简写形式。

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

package main

import "sort"

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

> The Go Programming Language Specification
>
> Slice expressions
>
> Slice expressions construct a substring or slice from a string, array,
> pointer to array, or slice. There are two variants: a simple form that
> specifies a low and high bound, and a full form that also specifies a
> bound on the capacity.
>
> Simple slice expressions
>
> For a string, array, pointer to array, or slice a, the primary
> expression
>
> a[low : high]
>
> constructs a substring or slice. The indices low and high select which
> elements of operand a appear in the result. The result has indices
> starting at 0 and length equal to high - low. After slicing the array
> a
>
> a := [5]int{1, 2, 3, 4, 5}
> s := a[1:4]
>
> the slice s has type []int, length 3, capacity 4, and elements
>
> s[0] == 2
> s1 == 3
> s2 == 4
>
> For convenience, any of the indices may be omitted. A missing low
> index defaults to zero; a missing high index defaults to the length of
> the sliced operand:
>
> a[2:] // same as a[2 : len(a)]
> a[:3] // same as a[0 : 3]
> a[:] // same as a[0 : len(a)]
>
> If a is a pointer to an array, a[low : high] is shorthand for (*a)[low
> : high].

To convert type [5]int to type []int, slice the array. For example,

package main

import &quot;sort&quot;

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

答案3

得分: 0

var distancematrix [5][5]int,将创建一个大小为5 * 5的整数多维数组切片。当你尝试访问distancematrix[0]时,它返回类型为[5]int的整数数组切片。而sort.Ints期望的类型是[]int。

下面我声明了类型为[][]int的distancematrix,因此distancematrix[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])
}
英文:

var distancematrix [5][5]int, will create multidimensional array slice of 5 * 5 int. And when you try to access distancematrix[0], it returns int array slice of type [5]int. Where as sort.Ints expects type []int.

Here below I have declared distancematrix of type [][] and hence distancematrix[0] returns slice array of type []int.

package main

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

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

huangapple
  • 本文由 发表于 2015年11月18日 21:11:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/33781020.html
匿名

发表评论

匿名网友

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

确定