AmbieGirl
AmbieGirl

Reputation: 119

How to count the most frequent letter in a string?

class MyString:
    def __init__(self, myString):
        self.__myString = myString

    def countWord(self):
         count = len(self.__myString.split())
         return count

    def findMostFrequentChar(self):
        # ?

I need to implement findMostFrequenctChar. The only hint she gave us was that we needed to make 2 lists. and this is where she lost me.

Here's the code that calls the function:

def main():
    aString = MyString("This is a super long long long string. Please help count me")
    print("There are", aString.countWord(), "words in the string.")

    count, letter = aString.findMostFrequentChar()
    print("The most frequent character is", letter, "which appeared", count, "times")

main()

Upvotes: 5

Views: 10700

Answers (6)

David Bern
David Bern

Reputation: 776

I would use a dict to store the counting. But first I want to strip all spaces and other symbols then a-z, I also want to count upper & lower-case letters as one and the same.

When the dict is constructed with all my values I use the max function. The max takes a iterable, so we pass dict as a "list" of tuples (key, val). We need to tell max how to determine what we want to compare, for that we give a lambda function that takes the second element (val) in tuple to the key-arg.

In return, max will spit out the tuple with the highest val.

class MyString:

    def __init__(self, myString):
        self.__myString = myString

    def countWord(self):
        count = len(self.__myString.split())
        return count

    def findMostFrequentChar(self):
        counter = {}
        # Instead of performing various modifications on the string
        # one can instead filter all the undesired chars.
        # new_string = self.__myString.replace(' ', '').lower()
        new_string = list(filter(lambda x: 'a' >= x <= 'z', self.__myString.lower()))
        for char in new_string:

            if char in counter:
                counter[char] += 1
            else:
                counter[char] = 1

        key, value = max(counter.items(), key=lambda x:x[1])
        return value, key


def main():
    aString = MyString("This is a super long long long string. Please help count me")
    print("There are", aString.countWord(), "words in the string.")

    count, letter = aString.findMostFrequentChar()
    print("The most frequent character is", letter, "which appeared", count, "times")

main()

Upvotes: 1

janos
janos

Reputation: 124646

The only hint she gave us was that we needed to make 2 lists. and this is where she lost me.

That seems to imply that you cannot use collections.Counter, and probably not even dictionaries.

If we can assume that letters are defined as the English alphabet, then one list is enough. In that case, you could create a list of 26 items, all initialized to 0. Then you could iterate over the characters of the string, and for each letter of the English alphabet, increment the count of the n-th item in the list, where n is the index of the letter in the alphabet.

Create a list of 26 zeros:

counts = [0] * 26

Loop over the characters of the input string s:

for c in s:

Check that the character is a letter:

if 'a' <= c.lower() <= 'z'

Calculate the 0-based index of the letter in the alphabet and increment the count:

index = ord(c.lower()) - ord('a')
counts[index] += 1

Once you have the counts, you can find the index that has the maximum value (left for you as an exercise), and get the corresponding character with chr(index + ord('a')).

Upvotes: 4

Ajax1234
Ajax1234

Reputation: 71451

You can use sorted:

class String:
    def __init__(self, s):   
       self.s = s
    def findMostFrequentChar(self):
       return sorted([(a, self.s.count(a)) for a in self.s], key=lambda x:x[-1])[-1]

Upvotes: 3

neehari
neehari

Reputation: 2612

If you could use Counter from collections module:

from collections import Counter

def findMostFrequentChar(self):
    d = Counter(self.__myString.replace(' ', '').lower())        
    return d.most_common()[0]

If Counter is out of the question:

def findMostFrequentChar(self):
    d = {}

    for ch in self.__myString.replace(' ', '').lower():
        if ch in d:
            d[ch] += 1
        else:
            d[ch] = 1

    most_frequent = max(d, key=d.get)
    return most_frequent, d[most_frequent]

Putting it altogether:

class MyString:
    def __init__(self, myString):
        self.__myString = myString

    def countWord(self):
         count = len(self.__myString.split())
         return count

    def findMostFrequentChar(self):        
        d = {}

        for ch in self.__myString.replace(' ', '').lower():
            if ch in d:
                d[ch] += 1
            else:
                d[ch] = 1
        most_frequent = max(d, key=d.get)
        return most_frequent, d[most_frequent]


def main():    
    aString = MyString("This is a super long long long string. Please help count me")
    print("There are", aString.countWord(), "words in the string.")

    letter, count = aString.findMostFrequentChar()
    print("The most frequent character is", letter, "which appeared", count, "times")

main()

Upvotes: 2

user2390182
user2390182

Reputation: 73460

The "two list" part is irritating. One practical tool, however, to count elements of iterables in Python is collections.Counter:

from collections import Counter

# ...
    def findMostFrequentChar(self):
        return Counter(self.__myString).most_common()[0][0]

Upvotes: 0

timgeb
timgeb

Reputation: 78690

I will show you how to get the most frequent letter of a regular string by using a dictionary without any imports. Your job is to adjust your class accordingly.

I assume that if two or more letters share the highest frequency any one of them is a valid result.

>>> s = 'aabacbcd'
>>> counts = {}
>>> for c in s:
...     counts[c] = counts.get(c, 0) + 1
... 
>>> counts
{'a': 3, 'c': 2, 'b': 2, 'd': 1}
>>> max(counts, key=counts.get)
'a'

Upvotes: 1

Related Questions