找到文本中最常见的字符

时间:2017-03-17 12:23:54

标签: go

我需要实现一个包含接口的包,其中包含接收文本文件并对其执行分析的方法 - 计算字符总数并查找最常用的符号和单词。为了找到最频繁的字符,我遍历文本中的每个符文,将其转换为字符串并将其作为键添加到map。该值是递增计数器,用于计算此字符在给定文本中出现的频率。现在我遇到了以下问题 - 我无法弄清楚如何在地图中获得具有最高价值的密钥。这是代码:

package textscanner

import (
    "fmt"
    "log"
    "io/ioutil"
    "unicode/utf8"
    "strconv"
)

// Initializing my scanner
type Scanner interface {
    countChar(text string) int

    frequentSym(text string) // Return value is not yet implemented

    Scan()

    Run()
}

/* method counting characters */
func countChar(sc Scanner, text string) int { ... }

func frequentSym(sc Scanner, text string) {
    // Make a map with string key and integer value
    symbols := make(map[string] int)

    // Iterate through each char in text
    for _, sym := range text {
        // Convert rune to string
        char := strconv.QuoteRune(sym)
        // Set this string as a key in map and assign a counter value 
        count := symbols[char]

        if count == symbols[char] {
            // increment the value
            symbols[char] = count + 1
        } else {
            symbols[char] = 1
        }
    }
}

所以,基本上我需要找到一个具有最高int值的对并返回一个与它对应的string键,这是文本中最常用的字符

2 个答案:

答案 0 :(得分:3)

迭代地图:

maxK := ""
maxV := 0
for k, v := range symbols {
    if v > maxV {
        maxV = v
        maxK = k
    }
}
// maxK is the key with the maximum value.

答案 1 :(得分:1)

扩展@Ainar-G 答案,如果您的地图可能包含出现相同次数的多个键,那么@Ainar-G 代码每次都可能返回不同的结果,因为 Go 地图本质上是无序的;换句话说,映射中第一个值高于所有先前值的键成为最高键,但您并不总是知道该值是否会首先出现在映射中。以 this 为例。

为了使代码具有确定性,您需要解决两个键具有相同值的情况。如果值相同,一个简单的实现是进行字符串比较。

maxK := ""
maxV := 0
for k, v := range symbols {
    if v > maxV || (v == maxV && k < maxK) {
        maxV = v
        maxK = k
    }
}