Sorting 通过频率映射对字符串片段进行排序
我有一个字符串片段,想按频率对它们进行排序,我试图按照这里文档中的byAge示例进行排序,但无法将频率列表传递给它 也就是说,该示例的结果将是:Sorting 通过频率映射对字符串片段进行排序,sorting,go,Sorting,Go,我有一个字符串片段,想按频率对它们进行排序,我试图按照这里文档中的byAge示例进行排序,但无法将频率列表传递给它 也就是说,该示例的结果将是: [[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"}}
[[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)
}
如果在排序过程中需要的数据多于要排序的数据,通常的方法是 要实现自己的结构,是的。在您的情况下,这将是类似于()的内容:
数据
将是带有字符串和频率的片段
您的特定频率表
以下实现可用于排序
接口:
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]
}
如果频率表是常量,当然可以在包级别声明它
如果您还想对外部切片进行排序,则必须对内部切片进行排序
首先是外部切片。例如
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)
}
当计算密钥是一个简单的映射查找时,由于额外的分配和复制,这种解决方案可能不值得。对于计算起来很昂贵的密钥,这可能是一种改进。
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]]