Q:

C++ count and map

I am counting the number of times every word occurs in a text file. I would like to avoid cases and hence am doing tolower to my input and then counting. I have a map data structure having string and int to keep count. Now, when I output the word and its count, I don't want the word to be in lower case, but want it to maintain its original case. So, for counting all the words should change to lowercase but while giving output they all should be in their original case. Is there anyway to achieve this with using only one map?

A:

The third template parameter of std::map is a comparator type. You can provide your own comparison operation, in your case a case-insensitive one.
struct CaseInsensitive {
  bool operator()(std::string const& left, std::string const& right) const {
    size_t const size = std::min(left.size(), right.size());

    for (size_t i = 0; i != size; ++i) {
      char const lowerLeft = std::tolower(left[i]);
      char const lowerRight = std::tolower(right[i]);

      if (lowerLeft < lowerRight) { return true; }
      if (lowerLeft > lowerRight) { return false; }

      // if equal? continue!
    }

    // same prefix? then we compare the length
    return left.size() < right.size();
  }
};

Then instanciate your map:
typedef std::map<std::string, unsigned, CaseInsensitive> MyWordCountingMap;

Note: only the first spelling is preserved (which seems okay with you)

