Reputation:
I was trying to solve a particular problem from c++ primer book regarding maps & sets in which I have to make a map container which works as a word counter but I have to ignore punctuation & cases. For example, “example.” “example,” and “Example” should all increment the same key in the word counter.
Basic code of the map is as follows :-
map<string, size_t> word_count;
string word;
while (cin >> word)
++word_count[word];
for (const auto &a : word_count)
cout <<a.first<<" occurs "<<a.second<<((a.second>1) ? " times" : " time");
So what should I add into this code so that my word counter would ignore cases & punctuation on same words?
Upvotes: 0
Views: 174
Reputation: 8491
#include <map>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using std::map;
using std::cin;
using std::cout;
using std::endl;
using std::string;
using std::getline;
using std::transform;
using std::remove_if;
int main( int, char** )
{
map< string, string::size_type > dictionary;
string word = "";
while ( getline( cin, word ) )
{
word.erase( remove_if( word.begin( ), word.end( ), ::isspace ), word.end( ) );
word.erase( remove_if( word.begin( ), word.end( ), ::ispunct ), word.end( ) );
transform( word.begin( ), word.end( ), word.begin( ), ::tolower );
dictionary[ word ]++;
}
for ( const auto& entry : dictionary )
{
auto word = entry.first;
auto count = entry.second;
cout << "'" << word << "' total count: " << count << endl;
}
return EXIT_SUCCESS;
}
Build
clang++ -stdlib=libc++ -std=c++11 -o homework homework.cpp
Resources
Upvotes: 1
Reputation: 2231
You can use tolower:
#include <algorithm>
#include <string>
std::string str = "ExampleText";
std::transform(str.begin(), str.end(), str.begin(), ::tolower);
Also remove all punctuation symbols. For this you'll have to use custom algorithm.
Upvotes: 0