1

Currently, I am in the midst of writing a program that calculates all of the non white space characters in a user submitted string and then returns the most frequently used character. I cannot use collections, a counter, or the dictionary. Here is what I want to do:

Split the string so that white space is removed. Then count each character and return a value. I would have something to post here but everything I have attempted thus far has been met with critical failure. The closest I came was this program here:

strin=input('Enter a string: ')
fc=[]
nfc=0
for ch in strin:
    i=0
    j=0
while i<len(strin):
    if ch.lower()==strin[i].lower():
        j+=1
        i+=1
    if j>nfc and ch!=' ':
        nfc=j
        fc=ch
    print('The most frequent character in string is: ', fc )

If you can fix this code or tell me a better way of doing it that meets the required criteria that would be helpful. And, before you say this has been done a hundred times on this forum please note I created an account specifically to ask this question. Yes there are a ton of questions like this but some that are reading from a text file or an existing string within the program. And an overwhelmingly large amount of these contain either a dictionary, counter, or collection which I cannot presently use in this chapter.

Dimitris Fasarakis Hilliard
  • 150,925
  • 31
  • 268
  • 253

3 Answers3

2

Just do it "the old way". Create a list (okay it's a collection, but a very basic one so shouldn't be a problem) of 26 zeroes and increase according to position. Compute max index at the same time.

strin="lazy cat dog whatever"
l=[0]*26

maxindex=-1
maxvalue=0
for c in strin.lower():
    pos = ord(c)-ord('a')
    if 0<=pos<=25:
        l[pos]+=1
        if l[pos]>maxvalue:
            maxindex=pos
            maxvalue = l[pos]

print("max count {} for letter {}".format(maxvalue,chr(maxindex+ord('a'))))

result:

max count 3 for letter a
Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
  • Here's [a version that supports arbitrary Unicode strings, not just ASCII letters](http://stackoverflow.com/a/40567434/4279) – jfs Nov 12 '16 at 20:45
0

As an alternative to Jean's solution (not using a list that allows for one-pass over the string), you could just use str.count here which does pretty much what you're trying to do:

strin = input("Enter a string: ").strip()
maxcount = float('-inf')
maxchar = ''
for char in strin:
    c = strin.count(char) if not char.isspace() else 0
    if c > maxcount:
        maxcount = c
        maxchar = char
print("Char {}, Count {}".format(maxchar, maxcount))

If lists are available, I'd use Jean's solution. He doesn't use a O(N) function N times :-)

P.s: you could compact this with one line if you use max:

max(((strin.count(i), i) for i in strin if not i.isspace()))
Dimitris Fasarakis Hilliard
  • 150,925
  • 31
  • 268
  • 253
  • I tested this one as well, and while its better then anything I have been able to do recently. It was yielding the second most frequently used letter in this sentence. "There is a string to search the most frequent character in it." Which is e. Not sure why it didn't return T as 8. –  Nov 12 '16 at 13:52
0

To keep track of several counts for different characters, you have to use a collection (even if it is a global namespace implemented as a dictionary in Python).

To print the most frequent non-space character while supporting arbitrary Unicode strings:

import sys

text = input("Enter a string (case is ignored)").casefold() # default caseless matching

# count non-space character frequencies
counter = [0] * (sys.maxunicode + 1)
for nonspace in map(ord, ''.join(text.split())):
    counter[nonspace] += 1

# find the most common character
print(chr(max(range(len(counter)), key=counter.__getitem__)))

A similar list in Cython was the fastest way to find frequency of each character.

Community
  • 1
  • 1
jfs
  • 399,953
  • 195
  • 994
  • 1,670