Generally, when wanting the frequency of any object within a specified range, you want your frequency array to cover the entire range of possible values for that object. For a full explanation of what is frequency array is, and how to use it, a fuller explanation is provided in answer to How to remove duplicate char in string in C
In this case for ASCII characters, you have a range of 128 possible value (or 256 if you include the extended ASCII set), See ASCII Table & Description. By creating your frequency array with 128 (or 256) elements, you eliminate having to check for special cases such as lower/uppercase characters.
For example, you could cover all ASCII characters and find the most frequent a user may enter with the following:
#include <stdio.h>
#include <ctype.h>
#define SIZE 256 /* size works for both frequency array and text as a multiple */
int main (void) {
char text[SIZE * 4]; /* 1024 byte buffer */
int freq[SIZE] = {0}, max = 0; /* frequeny array & max */
fputs ("enter string: ", stdout); /* prompt */
if (!fgets (text, SIZE, stdin)) { /* read/validate EVERY input */
puts ("(user canceled input)");
return 0;
}
for (int i = 0; text[i]; i++) /* loop over each char */
if (++freq[(unsigned char)text[i]] > max) /* increment/check against max */
max = freq[(unsigned char)text[i]];
printf ("\nmost frequent appear %d times: ", max);
for (int i = '!'; i < SIZE; i++) /* loop over freq array */
if (freq[i] == max) /* if count == max */
putchar (i); /* output char */
putchar ('\n'); /* tidy up with newline */
}
(note: since a user may validly cancel input generating a manual EOF
by pressing Ctrl + d, or Ctrl + z on windows, it is good to validate every input and handle the EOF
case as well as any other possible failure modes)
Since ASCII characters below ' '
(space, 32
, 0x20
) are non-printable or whitespace such as '\t'
, '\n'
, \r
, etc.., you can begin your output loop with the '!'
character to ignore whitespace. If you need the frequency of every character, you can create a short lookup table with the string representations of each non-printable or whitespace character. That way if the ' '
character were the, or one of the, most frequent characters, you could output, e.g. "(sp)"
or something similar, "(tab)"
for tab, etc..
Example Use/Output
$ ./bin/badfreq
enter string: 123+HH~helloo+345
most frequent appear 2 times: +3Hlo
Saving Most Frequent Characters To Array
There are very few changes needed to buffer the most frequently occurring characters in an array instead of directly outputting them with putchar()
. All you need to do is declare an array of sufficient size to hold the maximum number of possible characters (+1
to allow space for a nul-terminating character if you wish to treat the array as a C-string.
Below we add the buffer (character array) most_freq[]
to hold the most frequently used characters, and the fill the most_freq[]
array where we were simply outputting it in the first example, e.g.
#include <stdio.h>
#include <ctype.h>
#define SIZE 256 /* size works for both frequency array and text as a multiple */
int main (void) {
char text[SIZE * 4], /* 1024 byte read buffer */
most_freq[SIZE + 1] = ""; /* 257 byte buffer for storage */
int freq[SIZE] = {0}, /* frequeny array */
max = 0, /* times most frequent occurs */
mf_ndx = 0; /* most_frequent index */
fputs ("enter string: ", stdout); /* prompt */
if (!fgets (text, SIZE, stdin)) { /* read/validate EVERY input */
puts ("(user canceled input)");
return 0;
}
for (int i = 0; text[i]; i++) /* loop over each char */
if (++freq[(unsigned char)text[i]] > max) /* increment/check against max */
max = freq[(unsigned char)text[i]];
for (int i = '!'; i < SIZE; i++) /* loop over freq array */
if (freq[i] == max) /* if count == max */
most_freq[mf_ndx++] = i; /* store in most_freq array */
most_freq[mf_ndx] = 0; /* nul-terminate as string */
printf ("\n%d most frequent chars appear %d times: %s\n", /* output results */
mf_ndx, max, most_freq);
}
Following exit of the loop we use to fill the array, we add the nul-termianting character '\0'
(same as plain old ASCII 0
) after the last character added so we can then treat the most_freq[]
array as a string.
Example Use/Output
This does allow a simple way to provide a bit more information in the output, e.g.
$ ./bin/most_freq_array
enter string: 123+HH~helloo+345
5 most frequent chars appear 2 times: +3Hlo
Or in your specific example case of "helloo"
:
$ ./bin/most_freq_array
enter string: helloo
2 most frequent chars appear 2 times: lo
Look things over and let me know if your have further questions.