AlexNikolaev94
AlexNikolaev94

Reputation: 1209

Find the most frequent character in text

I need to implement a package with interface with methods that take text file and performs analysis on it - counts the total amount of characters and finds the most frequent symbol and word. To find the most frequent character I loop through each rune in the text, convert it to string and append it as a key to map. The value is an incremented counter which counts how often this character occurs in the given text. Now I'm stuck a little with the following problem -- I can't figure out how to get the key with the highest value in my map. Here's the code:

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

So, basically I need to find a pair with the highest int value and return a string key that corresponds to it, that is the most frequent character in text

Upvotes: 0

Views: 1825

Answers (2)

Clark McCauley
Clark McCauley

Reputation: 1457

Expanding on @Ainar-G answer, if there is a possibility that your map could contain multiple keys that occur the same number of times, then @Ainar-G code could return different results every time because Go maps are inherently unordered; in other words, the first key in your map to have a value higher then all previous values becomes the highest key, but you don't always know whether that value will occur first in the map. See this as an example.

In order for the code to be deterministic, you will need to address the case where two keys have the same value. A simple implementation would be to do a string comparison if the value is the same.

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

Upvotes: 1

Ainar-G
Ainar-G

Reputation: 36259

Just iterate over the map:

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

Upvotes: 3

Related Questions