英文:
Sorting slices of strings by a map of their frequencies
问题
我有一个字符串切片的切片,并希望按照它们的频率进行排序。我尝试按照文档中的byAge示例(http://golang.org/pkg/sort/)的方法,但是不知道如何将频率列表传递给它。
意思是,示例的结果应该是:
[[a,b] [a,b,c,d] [a,c,d,e]]
是否可以通过使用自定义结构来表示"a",并将频率作为它自己的属性来实现?这似乎更符合byAge示例的方式。
func main() {
transactions := [][]string{{"a", "b"}, {"b", "c", "d", "a"}, {"c", "d", "e", "a"}}
frequencies := map[string]int{
"a": 3,
"b": 2,
"c": 2,
"d": 2,
"e": 1,
}
fmt.Println(transactions, frequencies)
}
英文:
I have a slice of slices of strings, and want to sort them by their frequency, I tried to follow the byAge example from the docs here http://golang.org/pkg/sort/ but was unable how to pass a list of frequencies to it.
Meaning, the outcome of the example would be:
[[a,b] [a,b,c,d] [a,c,d,e]]
Would the approach be to have "a" be represented by a custom struct with frequency as it's own attribute? That seems to be more in line with the byAge example.
func main() {
transactions := [][]string{{"a", "b"}, {"b", "c", "d", "a"}, {"c", "d", "e", "a"}}
frequencies := map[string]int{
"a": 3,
"b": 2,
"c": 2,
"d": 2,
"e": 1,
}
fmt.Println(transactions, frequencies)
}
答案1
得分: 4
如果在排序过程中需要更多的数据,一种常见的方法是实现自己的结构体。在你的情况下,可以像这样实现一个结构体:
type SortableTransaction struct {
data []string
frequencies map[string]int
}
data
是包含字符串的切片,frequencies
是特定频率表。
下面的实现可以用于 Sort
接口:
func (s SortableTransaction) Len() int { return len(s.data) }
func (s SortableTransaction) Less(i, j int) bool {
return s.frequencies[s.data[i]] > s.frequencies[s.data[j]]
}
func (s SortableTransaction) Swap(i, j int) {
s.data[j], s.data[i] = s.data[i], s.data[j]
}
如果你的频率表是常量的,当然可以在包级别声明它。
如果你想要对外部切片进行排序,你需要先对内部切片进行排序,然后再对外部切片进行排序。
英文:
In case you need more than the data you want to sort in the sorting process, a common way is
to implement your own struct, yes. In your case this would be something like this (on play):
type SortableTransaction struct {
data []string
frequencies map[string]int
}
data
would be the slice with strings and frequencies
your specific frequency table.
The following implementation could be used for the Sort
interface:
func (s SortableTransaction) Len() int { return len(s.data) }
func (s SortableTransaction) Less(i, j int) bool {
return s.frequencies[s.data[i]] > s.frequencies[s.data[j]]
}
func (s SortableTransaction) Swap(i, j int) {
s.data[j], s.data[i] = s.data[i], s.data[j]
}
If your frequency table is constant, you can declare it at package level of course.
In case you want to sort the outer slice as well, you'd have to sort the inner slices
first and then the outer slices.
答案2
得分: 1
例如,
package main
import (
"fmt"
"sort"
)
type NameFrequency struct {
Name string
Frequency int
}
func (nf NameFrequency) String() string {
return fmt.Sprintf("%s: %d", nf.Name, nf.Frequency)
}
type ByFrequency []NameFrequency
func (nf ByFrequency) Len() int { return len(nf) }
func (nf ByFrequency) Swap(i, j int) { nf[i], nf[j] = nf[j], nf[i] }
func (nf ByFrequency) Less(i, j int) bool {
less := nf[i].Frequency > nf[j].Frequency
if nf[i].Frequency == nf[j].Frequency {
less = nf[i].Name < nf[j].Name
}
return less
}
func SortByFrequency(names []string, frequencies map[string]int) []string {
nf := make(ByFrequency, len(names))
for i, name := range names {
nf[i] = NameFrequency{name, frequencies[name]}
}
sort.Sort(ByFrequency(nf))
sortedNames := make([]string, len(names))
for i, nf := range nf {
sortedNames[i] = nf.Name
}
return sortedNames
}
func main() {
transactions := [][]string{{"a", "b"}, {"b", "c", "d", "a"}, {"c", "d", "e", "a"}}
fmt.Println(transactions)
frequencies := map[string]int{
"a": 3,
"b": 2,
"c": 2,
"d": 2,
"e": 1,
}
fmt.Println(frequencies)
sortedTransactions := make([][]string, len(transactions))
for i, transaction := range transactions {
sortedTransactions[i] = SortByFrequency(transaction, frequencies)
}
fmt.Println(sortedTransactions)
}
输出:
[[a b] [b c d a] [c d e a]]
map[a:3 b:2 c:2 d:2 e:1]
[[a b] [a b c d] [a c d e]]
英文:
For example,
package main
import (
"fmt"
"sort"
)
type NameFrequency struct {
Name string
Frequency int
}
func (nf NameFrequency) String() string {
return fmt.Sprintf("%s: %d", nf.Name, nf.Frequency)
}
type ByFrequency []NameFrequency
func (nf ByFrequency) Len() int { return len(nf) }
func (nf ByFrequency) Swap(i, j int) { nf[i], nf[j] = nf[j], nf[i] }
func (nf ByFrequency) Less(i, j int) bool {
less := nf[i].Frequency > nf[j].Frequency
if nf[i].Frequency == nf[j].Frequency {
less = nf[i].Name < nf[j].Name
}
return less
}
func SortByFrequency(names []string, frequencies map[string]int) []string {
nf := make(ByFrequency, len(names))
for i, name := range names {
nf[i] = NameFrequency{name, frequencies[name]}
}
sort.Sort(ByFrequency(nf))
sortedNames := make([]string, len(names))
for i, nf := range nf {
sortedNames[i] = nf.Name
}
return sortedNames
}
func main() {
transactions := [][]string{{"a", "b"}, {"b", "c", "d", "a"}, {"c", "d", "e", "a"}}
fmt.Println(transactions)
frequencies := map[string]int{
"a": 3,
"b": 2,
"c": 2,
"d": 2,
"e": 1,
}
fmt.Println(frequencies)
sortedTransactions := make([][]string, len(transactions))
for i, transaction := range transactions {
sortedTransactions[i] = SortByFrequency(transaction, frequencies)
}
fmt.Println(sortedTransactions)
}
Output:
[[a b] [b c d a] [c d e a]]
map[a:3 b:2 c:2 d:2 e:1]
[[a b] [a b c d] [a c d e]]
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论