1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
|
#include <iostream>
#include <string>
#include <locale>
#include <algorithm>
#include <map>
#include <functional>
#include <fstream>
#include <iterator>
// word: sequence of characters without embedded whitespace
// and without leading or trailing non-alpha characters
// with all the characters converted to lower case
std::istream& getword( std::istream& stm, std::string& word )
{
const auto& loc = stm.getloc() ;
const auto alpha = [&loc]( char c ) { return std::isalpha( c, loc ) ; } ;
while( stm >> word )
{
const auto begin = std::find_if( word.begin(), word.end(), alpha ) ;
if( begin != word.end() )
{
word = { begin, std::find_if( word.rbegin(), word.rend(), alpha ).base() } ;
for( char& c : word ) c = std::tolower( c, loc ) ;
return stm ;
}
}
return stm ;
}
std::map< std::string, int > make_word_count( std::istream& stm )
{
std::map< std::string, int > wc ;
std::string word ;
while( getword( stm, word ) ) ++wc[word] ;
return wc ;
}
template < typename OUTPUT_ITERATOR >
OUTPUT_ITERATOR copy_most_used( const std::map< std::string, int >& wc,
OUTPUT_ITERATOR dest, std::size_t n = 5 )
{
std::multimap< int, std::reference_wrapper<const std::string> > inverted_map ;
for( const auto& pair : wc )
inverted_map.emplace( pair.second, std::cref(pair.first) ) ;
n = std::min( wc.size(), n ) ;
auto end = inverted_map.rbegin() ;
std::advance( end, n ) ;
for( auto iter = inverted_map.rbegin() ; iter != end ; ++iter, ++dest )
*dest = iter->second ;
return dest ;
}
int main()
{
std::ifstream file( __FILE__ ) ;
const auto word_count = make_word_count(file) ;
std::cout << "most used words\n--------------\n" ;
copy_most_used( word_count, std::ostream_iterator<std::string>( std::cout, "\n" ) ) ;
}
| |