#include <iostream>
#include <string>
#include <set>
#include <sstream>
#include <iterator>
#include <cctype>
#include <algorithm>
using namespace std;
bool isWordSeparator(char & c) {
return c == ' ' || c == '-' || c == '\n' || c == '?' || c == '.' || c == ','
|| c == '?' || c == '!' || c == ':' || c == ';';
}
int main()
{
string s = "ab\nAb!aB?AB:ab.AB;ab\nAB\nZZZZ zzzz Zzzz\nzzzz";
transform(s.begin(),s.end(),s.begin(),
[](char c)->char { if(isWordSeparator(c)) return ' '; return tolower(c); });
istringstream iss(s);
//This will create a set of lowercase tokens, leaving the duplicates out:
set<string> words((istream_iterator<string>(iss)), istream_iterator<string>());
cout << "Number of Words: " << words.size() << endl;
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8c3RyaW5nPgojaW5jbHVkZSA8c2V0PgojaW5jbHVkZSA8c3N0cmVhbT4KI2luY2x1ZGUgPGl0ZXJhdG9yPgojaW5jbHVkZSA8Y2N0eXBlPgojaW5jbHVkZSA8YWxnb3JpdGhtPgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKYm9vbCBpc1dvcmRTZXBhcmF0b3IoY2hhciAmIGMpIHsKICAgIHJldHVybiBjID09ICcgJyB8fCBjID09ICctJyB8fCBjID09ICdcbicgfHwgYyA9PSAnPycgfHwgYyA9PSAnLicgfHwgYyA9PSAnLCcKICAgIHx8IGMgPT0gJz8nIHx8IGMgPT0gJyEnIHx8IGMgPT0gJzonIHx8IGMgPT0gJzsnOwp9CgoKaW50IG1haW4oKQp7CiAgICBzdHJpbmcgcyA9ICJhYlxuQWIhYUI/QUI6YWIuQUI7YWJcbkFCXG5aWlpaIHp6enogWnp6elxuenp6eiI7CgogICAgdHJhbnNmb3JtKHMuYmVnaW4oKSxzLmVuZCgpLHMuYmVnaW4oKSwKICAgICAgICBbXShjaGFyIGMpLT5jaGFyIHsgaWYoaXNXb3JkU2VwYXJhdG9yKGMpKSByZXR1cm4gJyAnOyByZXR1cm4gdG9sb3dlcihjKTsgfSk7CgogICAgaXN0cmluZ3N0cmVhbSBpc3Mocyk7CgogICAgLy9UaGlzIHdpbGwgY3JlYXRlIGEgc2V0IG9mIGxvd2VyY2FzZSB0b2tlbnMsIGxlYXZpbmcgdGhlIGR1cGxpY2F0ZXMgb3V0OgogICAgc2V0PHN0cmluZz4gd29yZHMoKGlzdHJlYW1faXRlcmF0b3I8c3RyaW5nPihpc3MpKSwgaXN0cmVhbV9pdGVyYXRvcjxzdHJpbmc+KCkpOwoKICAgIGNvdXQgPDwgIk51bWJlciBvZiBXb3JkczogIiA8PCB3b3Jkcy5zaXplKCkgIDw8IGVuZGw7CgogICAgcmV0dXJuIDA7Cn0=