2013-12-12 35 views
2

我有一段字符串片段,並且想按照它們的頻率對它們進行排序,我試圖按照文檔http://golang.org/pkg/sort/中的byAge示例進行排序,但無法如何傳遞它的頻率列表。通過頻率映射對字符串進行排序

含義,示例的結果將是:

[[a,b] [a,b,c,d] [a,c,d,e]] 

會的辦法是有「」用的頻率自定義的結構作爲它自己的屬性來表示?這似乎更符合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) 

} 

回答

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

例如,

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]] 
+1

當計算的關鍵是一個簡單的地圖查找,這種解決方案可能是不值得的,由於額外的分配和複製。對於昂貴的密鑰計算,這可能是一個改進。 –

相關問題