我无法按字符排序字符串(检查两个字符串是否为字谜,我想对它们进行排序,并检查是否相等)。
我可以像这样获得字符串[]rune
的{{1}}表示:
s
我可以像这样排序
runes := make([]rune, len(s))
copy(runes, []rune(s))
但someInts := []int{5, 2, 6, 3, 1, 4} // unsorted
sort.Ints(someInts)
只是rune
的别名,所以我应该可以致电
int32
然而,我收到错误:
sort.Ints(runes)
那么......我如何对int32,int64或int *进行排序?
编辑:我确实对我的符文进行了排序,但男孩,这很难看。
cannot use runes (type []rune) as type []int in function argument
所以基本上如果你有一些东西,你必须将它包装在一个实现type RuneSlice []rune
func (p RuneSlice) Len() int { return len(p) }
func (p RuneSlice) Less(i, j int) bool { return p[i] < p[j] }
func (p RuneSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
func sorted(s string) string {
runes := []rune(s)
sort.Sort(RuneSlice(runes))
return string(runes)
}
的类型中。所有这些实现都将具有完全相同的方法体(如sort.Interface
和sort.IntSlice
)。如果这真的是多么难看,那么为什么他们不在sort.Float64Slice
包中提供这些WhateverSlice包装?缺乏仿制药现在开始受到严重伤害。必须有一种更好的方法来分类。
答案 0 :(得分:7)
使用sort.Sort(data Interface)
并实施sort.Interface
,请参阅包文档中的示例。
您不能将rune
int32
用作int
。查看int
的{{3}}。
int是一个有符号整数类型,其大小至少为32位。它是一个 但是,不同的类型,而不是int32。
的别名
答案 1 :(得分:3)
实际上有一种软通用方式可以做你想要的。
查看以下包裹:
特别是以下文件:
https://github.com/BurntSushi/ty/blob/master/fun/sort_test.go
如何使用它的示例:
tosort := []int{10, 3, 5, 1, 15, 6}
fun.Sort(func(a, b int) bool {
return b < a
}, tosort)
在该软件包中通过反射实现了许多其他有趣的通用算法。
所有积分均转至@BurntSushi。
答案 2 :(得分:3)
注意:Go 1.8将引入帮助以对切片进行排序 请issue 16721
查看commit 22a2bdf和Brad Fitzpatrickvar strings = [...]string{"", "Hello", "foo", "bar", "foo", "f00", "%*&^*&^&", "***"}
func TestSlice(t *testing.T) {
data := strings
Slice(data[:], func(i, j int) bool {
return data[i] < data[j]
})
}
答案 3 :(得分:2)
作为一个比较点,如果排序界面略有不同,这里的内容可能会是什么样子。也就是说,如果接口位于元素上,而不是容器上的接口,那么它会是什么样的呢?
package main
import (
"fmt"
"sort"
)
type Comparable interface {
LessThan(Comparable) bool
}
type ComparableSlice []Comparable
func (c ComparableSlice) Len() int {
return len(c)
}
func (c ComparableSlice) Less(i, j int) bool {
return c[i].LessThan(c[j])
}
func (c ComparableSlice) Swap(i, j int) {
c[i], c[j] = c[j], c[i]
}
func SortComparables(elts []Comparable) {
sort.Sort(ComparableSlice(elts))
}
//////////////////////////////////////////////////////////////////////
// Let's try using this:
type ComparableRune rune
func (r1 ComparableRune) LessThan(o Comparable) bool {
return r1 < o.(ComparableRune)
}
func main() {
msg := "Hello world!"
comparables := make(ComparableSlice, len(msg))
for i, v := range msg {
comparables[i] = ComparableRune(v)
}
SortComparables(comparables)
sortedRunes := make([]rune, len(msg))
for i, v := range comparables {
sortedRunes[i] = rune(v.(ComparableRune))
}
fmt.Printf("result: %#v\n", string(sortedRunes))
}
在这里,我们定义一个Comparable
接口,我们得到类型ComparableRune
来满足它。但是因为它是一个界面,我们必须进行从rune
到ComparableRune
的笨拙拳击,以便动态调度可以启动:
comparables := make(ComparableSlice, len(msg))
for i, v := range msg {
comparables[i] = ComparableRune(v)
}
并取消装箱以取回我们的符文:
sortedRunes := make([]rune, len(msg))
for i, v := range comparables {
sortedRunes[i] = rune(v.(ComparableRune))
}
这种方法似乎要求我们知道如何在接口和值的动态类型之间来回进行类型转换。看起来我们需要使用Go的更多部分 - 更多的机制 - 而不是使用容器作为接口的方法。
答案 4 :(得分:1)
至少从2020年11月开始,https://golang.org/pkg/sort/提议使用作为闭包传递的自定义Less函数。下面的代码具有预期的效果:
package main
import (
"fmt"
"sort"
)
func main() {
s1 := "eidbaooo"
runeSlice := []rune(s1)
fmt.Println(string(runeSlice))
sort.Slice(runeSlice, func(i, j int) bool {
return runeSlice[i] < runeSlice[j]
})
fmt.Println(string(runeSlice))
}
输出:
eidbaooo
abdeiooo
这可以为您省去完整的接口实现。