#include <iostream>
#include <vector>
#include <string>
struct char_counter
{
char_counter( char first = 'a', char last = 'z' ) : first(first), last(last)
{ if( first <= last ) amounts.resize(last-first+1) ; }
char_counter& operator << ( char c )
{ if( c >= first && c <= last ) ++amounts[c-first] ; return *this ; }
char_counter& operator << ( const char* p )
{ for( ; *p != 0 ; ++p ) operator<< (*p) ; return *this ; }
char_counter& operator << ( const std::string& str )
{ for( char c : str ) operator<< (c) ; return *this ; }
std::vector<int> amounts ;
const char first ;
const char last ;
};
std::ostream& operator<< ( std::ostream& stm, const char_counter& counter )
{
stm << "counts [" << counter.first << '-' << counter.last << "]: { " ;
for( std::size_t i = 0 ; i < counter.amounts.size() ; ++i )
{
int cnt = counter.amounts[i] ;
if( cnt > 0 ) stm << char( i + counter.first ) << ':' << cnt << ' ' ;
}
return stm << '}' ;
}
int main()
{
char_counter counter ;
counter << 'a' << "abcde" << std::string("defg") << 'f' << "a?c?d?e?g?x" ;
std::cout << counter << '\n' ;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dmVjdG9yPgojaW5jbHVkZSA8c3RyaW5nPgoKc3RydWN0IGNoYXJfY291bnRlcgp7CiAgICBjaGFyX2NvdW50ZXIoIGNoYXIgZmlyc3QgPSAnYScsIGNoYXIgbGFzdCA9ICd6JyApIDogZmlyc3QoZmlyc3QpLCBsYXN0KGxhc3QpCiAgICB7IGlmKCBmaXJzdCA8PSBsYXN0ICkgYW1vdW50cy5yZXNpemUobGFzdC1maXJzdCsxKSA7IH0KCiAgICBjaGFyX2NvdW50ZXImIG9wZXJhdG9yIDw8ICggY2hhciBjICkKICAgIHsgaWYoIGMgPj0gZmlyc3QgJiYgYyA8PSBsYXN0ICkgKythbW91bnRzW2MtZmlyc3RdIDsgcmV0dXJuICp0aGlzIDsgfQoKICAgIGNoYXJfY291bnRlciYgb3BlcmF0b3IgPDwgKCBjb25zdCBjaGFyKiBwICkKICAgIHsgZm9yKCA7ICpwICE9IDAgOyArK3AgKSBvcGVyYXRvcjw8ICgqcCkgOyByZXR1cm4gKnRoaXMgOyB9CgogICAgY2hhcl9jb3VudGVyJiBvcGVyYXRvciA8PCAoIGNvbnN0IHN0ZDo6c3RyaW5nJiBzdHIgKQogICAgeyBmb3IoIGNoYXIgYyA6IHN0ciApIG9wZXJhdG9yPDwgKGMpIDsgcmV0dXJuICp0aGlzIDsgfQoKICAgIHN0ZDo6dmVjdG9yPGludD4gYW1vdW50cyA7CiAgICBjb25zdCBjaGFyIGZpcnN0IDsKICAgIGNvbnN0IGNoYXIgbGFzdCA7Cn07CgpzdGQ6Om9zdHJlYW0mIG9wZXJhdG9yPDwgKCBzdGQ6Om9zdHJlYW0mIHN0bSwgY29uc3QgY2hhcl9jb3VudGVyJiBjb3VudGVyICkKewogICAgc3RtIDw8ICJjb3VudHMgWyIgPDwgY291bnRlci5maXJzdCA8PCAnLScgPDwgY291bnRlci5sYXN0IDw8ICJdOiB7ICIgOwogICAgZm9yKCBzdGQ6OnNpemVfdCBpID0gMCA7IGkgPCBjb3VudGVyLmFtb3VudHMuc2l6ZSgpIDsgKytpICApCiAgICB7CiAgICAgICAgaW50IGNudCA9IGNvdW50ZXIuYW1vdW50c1tpXSA7CiAgICAgICAgaWYoIGNudCA+IDAgKSBzdG0gPDwgY2hhciggaSArIGNvdW50ZXIuZmlyc3QgKSA8PCAnOicgPDwgY250IDw8ICcgJyA7CiAgICB9CiAgICByZXR1cm4gc3RtIDw8ICd9JyA7Cn0KCmludCBtYWluKCkKewogICAgY2hhcl9jb3VudGVyIGNvdW50ZXIgOwogICAgY291bnRlciA8PCAnYScgPDwgImFiY2RlIiA8PCBzdGQ6OnN0cmluZygiZGVmZyIpIDw8ICdmJyA8PCAiYT9jP2Q/ZT9nP3giIDsKICAgIHN0ZDo6Y291dCA8PCBjb3VudGVyIDw8ICdcbicgOwp9Cg==