英文:
how to sort by indices in golang
问题
我正在努力将一些 Matlab 代码移植到 Golang,我想知道如何在 Golang 中获取数组排序后的索引,并如何使用这些索引重新排列另一个数组。例如,下面的 Matlab 代码可以实现这一点,但我无法找到在 Golang 中实现相同功能的方法。非常感谢您的帮助。
package main
import (
"fmt"
"sort"
)
func main() {
x := []int{3, 4, 2, 1, 6}
y := []int{11, 12, 15, 16, 17}
// 获取排序后的索引
sortedIndices := make([]int, len(x))
for i := range sortedIndices {
sortedIndices[i] = i
}
sort.Slice(sortedIndices, func(i, j int) bool {
return x[sortedIndices[i]] < x[sortedIndices[j]]
})
// 根据排序后的索引重新排列数组 y
c := make([]int, len(y))
for i, idx := range sortedIndices {
c[i] = y[idx]
}
fmt.Println(c) // 输出: [16 15 11 12 17]
}
希望对您有所帮助!
英文:
I'm having difficulty porting some code from matlab to golang
I want to know how can I get array indices after sorting them in golang, and then how can I use these indices to re-arrange another array? for example the matlab code below does that but I can't figure out doing the same thing in Go. Any help is deeply appreciated.
x=[3 4 2 1 6];
y=[11 12 15 16 17];
[sorted_x_vals, sorted_x_indices]=sort(x);
c=y(sorted_x_indices); // re-arrange y according to the sorted indices
// c= 16 15 11 12 17
Thanks a lot in advance
答案1
得分: 4
你可以创建一个sort.Interface
的实现来同时对切片进行排序,基于第一个切片的值:
type by struct {
Indices []int
Values []int
}
func (b by) Len() int { return len(b.Values) }
func (b by) Less(i, j int) bool { return b.Indices[i] < b.Indices[j] }
func (b by) Swap(i, j int) {
b.Indices[i], b.Indices[j] = b.Indices[j], b.Indices[i]
b.Values[i], b.Values[j] = b.Values[j], b.Values[i]
}
func main() {
x := []int{3, 4, 2, 1, 6}
y := []int{11, 12, 15, 16, 17}
sort.Sort(by{Indices: x, Values: y})
fmt.Println(x)
fmt.Println(y)
}
// [1 2 3 4 6]
// [16 15 11 12 17]
或者,如果你想要按照这种方式对任意数量的切片进行排序,你可以定义一个[][]int
类型,如下所示:
type matrix [][]int
func (m matrix) Len() int { return len(m[0]) }
func (m matrix) Less(i, j int) bool { return m[0][i] < m[0][j] }
func (m matrix) Swap(i, j int) {
for _, s := range m {
s[i], s[j] = s[j], s[i]
}
}
func main() {
x := []int{3, 4, 2, 1, 6}
y := []int{11, 12, 15, 16, 17}
z := []int{22, 33, 44, 55, 66}
sort.Sort(matrix{x, y, z})
fmt.Println(x)
fmt.Println(y)
fmt.Println(z)
}
// [1 2 3 4 6]
// [16 15 11 12 17]
// [55 44 22 33 66]
以上代码可以实现按照第一个切片的值对其他切片进行排序。
英文:
You can crate a sort.Interface
implementation to sort the slices in unison, based on the first slice's values:
https://play.golang.org/p/y0EFj8wUN0
type by struct {
Indices []int
Values []int
}
func (b by) Len() int { return len(b.Values) }
func (b by) Less(i, j int) bool { return b.Indices[i] < b.Indices[j] }
func (b by) Swap(i, j int) {
b.Indices[i], b.Indices[j] = b.Indices[j], b.Indices[i]
b.Values[i], b.Values[j] = b.Values[j], b.Values[i]
}
func main() {
x := []int{3, 4, 2, 1, 6}
y := []int{11, 12, 15, 16, 17}
sort.Sort(by{Indices: x, Values: y})
fmt.Println(x)
fmt.Println(y)
}
// [1 2 3 4 6]
// [16 15 11 12 17]
Or if you wanted to sort any number of slices like this you could define a [][]int
type like so
type matrix [][]int
func (m matrix) Len() int {return len(m[0])}
func (m matrix) Less(i, j int) bool { return m[0][i] < m[0][j] }
func (m matrix) Swap(i, j int) {
for _, s := range m {
s[i], s[j] = s[j], s[i]
}
}
func main() {
x := []int{3, 4, 2, 1, 6}
y := []int{11, 12, 15, 16, 17}
z := []int{22, 33, 44, 55, 66}
sort.Sort(matrix{x, y, z})
fmt.Println(x)
fmt.Println(y)
fmt.Println(z)
}
// [1 2 3 4 6]
// [16 15 11 12 17]
// [55 44 22 33 66]
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论