通过频率图对字符串切片进行排序

时间:2013-12-12 00:39:04

标签: sorting go

我有一片字符串片段,并希望按频率对它们进行排序,我尝试按照此处文档中的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)

}

2 个答案:

答案 0 :(得分:4)

如果您需要的数据超过要在排序过程中排序的数据,则常见的方法是 实现自己的结构,是的。在你的情况下,这将是这样的(on play):

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

如果您的频率表是常量,您当然可以在包级别声明它。

如果您想要对外部切片进行排序,则必须对内部切片进行排序 首先是外切片。

答案 1 :(得分: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]]