In a word, poorly. The basic idea is pretty simple, but the code is needlessly complex. In particular, his Symbol
member is completely useless.
What you'd normally want to do is something like this:
int counts[UCHAR_MAX] = {0};
size_t len = strlen(input_string);
for (int i=0; i<len; i++)
++counts[unsigned char(input_string[i])];
So, the basic idea here is pretty simple: walk through the string, and for each item in the string, increment the count for that character.
He's doing pretty much the same thing, but keeping the Count
as a member of a structure, along with the Symbol
. Since the Symbol
is always equal to the subscript of that item, storing it is pointless and wasteful.
Other than that, he's counting down in his loop -- probably a micro-optimization, because (at least on some machines) the zero flag will be set based on the value of the counter when it's decremented, so counting down to zero avoids a comparison in the loop. Given the amount he's wasting with his structure and unnecessarily storing the Symbol
values, this makes no sense at all.
If you honestly cared about the code being close to optimum, you could write something more like this:
int counts[UCHAR_MAX] = {0}:
while (*in)
++counts[(unsigned char)*in++];
For anybody wondering about the cast, it's unnecessary if you're sure your input will always be true ASCII, that never has the high-bit set. Since you can rarely guarantee much about the input, however, it's generally safer to cast to unsigned char. Otherwise, a character with its top-bit set will typically be interpreted as a negative number, and index outside the array bound. Of course, it's possible for char to be unsigned by default, but it's pretty rare. On a typical (two's complement) machine, the cast doesn't require any extra operations; it just governs how the existing bit pattern will be interpreted.