#include <map>
#include <iostream>
#include <iterator>
#include <algorithm>
#include <string>
#include <fstream>
#include <iomanip>
#include <locale>
#include <vector>
#include <unordered_set>
struct alpha_only: std::ctype<char> {
alpha_only() : std::ctype<char>(get_table()) {}
static std::ctype_base::mask const* get_table() {
static std::vector<std::ctype_base::mask>
rc(std::ctype<char>::table_size,std::ctype_base::space);
for (int i=0; i<std::ctype<char>::table_size; i++)
if (isalpha(i)) rc[i] = std::ctype_base::alpha;
rc['\''] = std::ctype_base::alpha;
return &rc[0];
}
};
typedef std::pair<std::string, unsigned> count;
namespace std {
std::ostream &operator<<(std::ostream &os, ::count const &c) {
return os << std::left << std::setw(25) << c.first
<< std::setw(10) << c.second;
}
}
int main(int argc, char **argv) {
std::locale loc(std::locale(), new alpha_only());
for (int i=1; i<argc; ++i) {
std::ifstream input(argv[i]);
input.imbue(loc);
std::map<std::string, unsigned> words;
std::for_each(std::istream_iterator<std::string>(input),
std::istream_iterator<std::string>(),
[&words](std::string const &w) { ++words[w]; });
std::copy(words.begin(), words.end(),
std::ostream_iterator<count>(std::cout, "\n"));
}
return 0;
}
I2luY2x1ZGUgPG1hcD4KI2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8aXRlcmF0b3I+CiNpbmNsdWRlIDxhbGdvcml0aG0+CiNpbmNsdWRlIDxzdHJpbmc+IAojaW5jbHVkZSA8ZnN0cmVhbT4KI2luY2x1ZGUgPGlvbWFuaXA+CiNpbmNsdWRlIDxsb2NhbGU+CiNpbmNsdWRlIDx2ZWN0b3I+CiNpbmNsdWRlIDx1bm9yZGVyZWRfc2V0PgoKc3RydWN0IGFscGhhX29ubHk6IHN0ZDo6Y3R5cGU8Y2hhcj4gewogICAgYWxwaGFfb25seSgpIDogc3RkOjpjdHlwZTxjaGFyPihnZXRfdGFibGUoKSkge30KCiAgICBzdGF0aWMgc3RkOjpjdHlwZV9iYXNlOjptYXNrIGNvbnN0KiBnZXRfdGFibGUoKSB7CiAgICAgICAgc3RhdGljIHN0ZDo6dmVjdG9yPHN0ZDo6Y3R5cGVfYmFzZTo6bWFzaz4gCiAgICAgICAgICAgIHJjKHN0ZDo6Y3R5cGU8Y2hhcj46OnRhYmxlX3NpemUsc3RkOjpjdHlwZV9iYXNlOjpzcGFjZSk7CiAgICAgICAgZm9yIChpbnQgaT0wOyBpPHN0ZDo6Y3R5cGU8Y2hhcj46OnRhYmxlX3NpemU7IGkrKykKICAgICAgICAgICAgaWYgKGlzYWxwaGEoaSkpIHJjW2ldID0gc3RkOjpjdHlwZV9iYXNlOjphbHBoYTsKICAgICAgICByY1snXCcnXSA9IHN0ZDo6Y3R5cGVfYmFzZTo6YWxwaGE7CiAgICAgICAgcmV0dXJuICZyY1swXTsKICAgIH0KfTsKCnR5cGVkZWYgc3RkOjpwYWlyPHN0ZDo6c3RyaW5nLCB1bnNpZ25lZD4gY291bnQ7CgpuYW1lc3BhY2Ugc3RkIHsgCiAgICBzdGQ6Om9zdHJlYW0gJm9wZXJhdG9yPDwoc3RkOjpvc3RyZWFtICZvcywgOjpjb3VudCBjb25zdCAmYykgeyAKICAgICAgICByZXR1cm4gb3MgPDwgc3RkOjpsZWZ0IDw8IHN0ZDo6c2V0dygyNSkgPDwgYy5maXJzdCAKICAgICAgICAgICAgICAgICAgICA8PCBzdGQ6OnNldHcoMTApIDw8IGMuc2Vjb25kOwogICAgfQp9CgppbnQgbWFpbihpbnQgYXJnYywgY2hhciAqKmFyZ3YpIHsgCiAgICBzdGQ6OmxvY2FsZSBsb2Moc3RkOjpsb2NhbGUoKSwgbmV3IGFscGhhX29ubHkoKSk7CiAgICBmb3IgKGludCBpPTE7IGk8YXJnYzsgKytpKSB7CiAgICAgICAgc3RkOjppZnN0cmVhbSBpbnB1dChhcmd2W2ldKTsKICAgICAgICBpbnB1dC5pbWJ1ZShsb2MpOwoKICAgICAgICBzdGQ6Om1hcDxzdGQ6OnN0cmluZywgdW5zaWduZWQ+IHdvcmRzOwogICAgCiAgICAgICAgc3RkOjpmb3JfZWFjaChzdGQ6OmlzdHJlYW1faXRlcmF0b3I8c3RkOjpzdHJpbmc+KGlucHV0KSwKICAgICAgICAgICAgICAgICAgICAgICAgc3RkOjppc3RyZWFtX2l0ZXJhdG9yPHN0ZDo6c3RyaW5nPigpLAogICAgICAgICAgICAgICAgICAgICAgICBbJndvcmRzXShzdGQ6OnN0cmluZyBjb25zdCAmdykgeyArK3dvcmRzW3ddOyB9KTsKICAgICAgICBzdGQ6OmNvcHkod29yZHMuYmVnaW4oKSwgd29yZHMuZW5kKCksCiAgICAgICAgICAgICAgICAgICAgc3RkOjpvc3RyZWFtX2l0ZXJhdG9yPGNvdW50PihzdGQ6OmNvdXQsICJcbiIpKTsKICAgIH0KICAgIHJldHVybiAwOwp9Cg==