doulubashang6936 2014-08-17 15:34
浏览 14
已采纳

如果无法使用Go lang对地图进行排序,那么正确的方法是什么?

Let's say I have a string and I would like to count each letter's frequency and then sort the table by the frequency. Desired output of "hello larry" would be:

+--------+-----------+
| Letter | Occurence |
+--------+-----------+
| l      |         3 |
| r      |         2 |
| h      |         1 |
| e      |         1 |
| o      |         1 |
| a      |         1 |
| y      |         1 |
+--------+-----------+

First I thought I'll deal with this easily using map having the letters as keys. This is really easy. However, map items don't have an order hence can't be sorted.

I guess I could deal with this using a structure:

type Letter struct {
    Value string
    Score int
}
type LetterList []Letter

However that brings bunch of other problems:

  1. I need to check if the Letter is not already present in LetterList because I can't use the letters as keys
  2. There's no direct way to sort them (using Int.sort() or so)

Using the structures just doesn't feel elegant at all. Is there a better solution?

  • 写回答

1条回答 默认 最新

  • dtcyv3985 2014-08-17 16:12
    关注

    You would be surprised how fast and efficient looping over a small slice is, and you can implement sorting on top of it fairly simple.

    I recommend reading http://golang.org/pkg/sort/ SortWrapper.

    type Letter struct {
        Value rune
        Score int
    }
    
    type LetterList []*Letter
    
    func (ll *LetterList) FindOrAdd(r rune) (l *Letter) {
        for _, l = range *ll {
            if l.Value == r {
                return
            }
        }
        l = &Letter{Value: r, Score: 0}
        *ll = append(*ll, l)
        return
    }
    
    func (ll LetterList) SortByScore() LetterList {
        sort.Sort(llByScore{ll})
        return ll
    }
    
    func (ll LetterList) SortByValue() LetterList {
        sort.Sort(llByValue{ll})
        return ll
    }
    
    func (ll LetterList) String() string {
        var b bytes.Buffer
        b.WriteByte('[')
        for _, v := range ll {
            b.WriteString(fmt.Sprintf("{%q, %d}, ", v.Value, v.Score))
        }
        b.WriteByte(']')
        return b.String()
    
    }
    
    func New(s string) (ll LetterList) {
        ll = LetterList{}
        for _, r := range s {
            ll.FindOrAdd(r).Score++
        }
        return
    }
    
    func (ll LetterList) Len() int      { return len(ll) }
    func (ll LetterList) Swap(i, j int) { ll[i], ll[j] = ll[j], ll[i] }
    
    type llByScore struct{ LetterList }
    
    func (l llByScore) Less(i, j int) bool {
        return l.LetterList[i].Score > l.LetterList[j].Score
    }
    
    type llByValue struct{ LetterList }
    
    func (l llByValue) Less(i, j int) bool {
        return l.LetterList[i].Value > l.LetterList[j].Value
    }
    
    func main() {
        ll := New(`Let's say I have a string and I would like to count each letter's frequency and then sort the table by the frequency. Desired output of "hello larry" would be`)
        fmt.Println(ll)
        fmt.Println(ll.SortByScore())
        fmt.Println(ll.SortByValue())
    }
    

    <kbd>playground</kbd>

    Another approach is to use a map then for sorting generate a list out of it and sort it.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥50 求解vmware的网络模式问题
  • ¥24 EFS加密后,在同一台电脑解密出错,证书界面找不到对应指纹的证书,未备份证书,求在原电脑解密的方法,可行即采纳
  • ¥15 springboot 3.0 实现Security 6.x版本集成
  • ¥15 PHP-8.1 镜像无法用dockerfile里的CMD命令启动 只能进入容器启动,如何解决?(操作系统-ubuntu)
  • ¥30 请帮我解决一下下面六个代码
  • ¥15 关于资源监视工具的e-care有知道的嘛
  • ¥35 MIMO天线稀疏阵列排布问题
  • ¥60 用visual studio编写程序,利用间接平差求解水准网
  • ¥15 Llama如何调用shell或者Python
  • ¥20 谁能帮我挨个解读这个php语言编的代码什么意思?