Ok, this is a range to value issue, and in this case you have very few ranges, but I still would prefer to see the use of a "map". Assuming percentage is an int, you could do something like this:
std::map< int, char > gradeMap;
// initialisation code, but can be read from config etc.
// Stored somewhere.
gradeMap[ 90 ] = 'A';
gradeMap[ 80 ] = 'B';
gradeMap[ 70 ] = 'C';
gradeMap[ 60 ] = 'D';
gradeMap[ 0 ] = 'F';
to look up my grade from a percentage, you can use
auto iter = gradeMap.upper_bound( grade );
This will actually get me the iterator one higher than the one I want. Thus if it is "begin" I have a grade 'Z' otherwise I should subtract one from the iterator.
if( iter == gradeMap.begin() )
However this is rather annoying. So there are 2 ways we can fix it. Either change the predicate in the map to sort downward. Or simply make our keys negative. We are hiding the implementation so it doesn't matter.
gradeMap[ -90 ] = 'A';
gradeMap[ -80 ] = 'B';
gradeMap[ -70 ] = 'C';
gradeMap[ -60 ] = 'D';
gradeMap[ 0 ] = 'F';
Now we can use
-grade. Note it changes from upper_bound before to lower_bound because of the case where our value is equal to the value.
The difference between
upper_bound is when the searched value equals the key, and this time we want the cell we are in, not the cell below it, so we want
If our percentage is, say 75 we would now search for -75 which falls between -80 and -70 but the lower bound is the one that has -70 because
lower_bound returns the first cell whose value is greater than or equal to the searched value. (
upper_bound returns the first cell whose value is strictly greater. It would work for -75 but not for -70 itself).
char get_grade( int percent )
auto iter = gradeMap.lower_bound( -percent );
if( iter == gradeMap.end() )
It's not really the place here to teach the user the full detail of what
std::map is. I will summarise to say firstly that it is one of the main collection classes in the standard library, and is mostly used as an associative array, that is, a unique key on which you look up and find its associated value. Used that way, the key either exists or it doesn't.
However there are occasions where you are not interested in exact key values but ranges, and you can take advantage of the fact that
map is a sorted container on its keys and that you can use
upper_range to find the points where your "key" belongs even if it is not actually in the container. (The only difference between lower_bound and upper_bound is when the key does exist). The fact that it returns an iterator, which can either point to one of the elements or one past the last one.
And that it is logarithmic in its lookup. For this instance where you have just 5 keys the performance doesn't really matter, but it's useful to know in general as part of your general education.
That you can use it to solve this particular kind of problem in C++ is useful. Some languages only use hash-table lookup for associative containers, which can be faster when it is only an exist/not exist situation but not useful for ranges at all.