#include #include #include #include #include #include using namespace std; string getCore (string word) { string result; for (unsigned i = 0; i < word.size(); ++i) { char c = word[i]; if (c >= 'A' && c <= 'Z') result += (c - 'A') + 'a'; else if (c >= 'a' && c <= 'z') result += c; } return result; } bool areSimilar (string word1, string word2) { if (word1.size() == word2.size() + 1) { // Try deleting characters from word1 for (unsigned i = 0; i < word1.size(); ++i) { if (word2 == word1.substr(0, i) + word1.substr(i+1)) return true; } } else if (word2.size() == word1.size() + 1) { // Try deleting characters from word2 for (unsigned i = 0; i < word2.size(); ++i) { if (word1 == word2.substr(0, i) + word2.substr(i+1)) return true; } } else if (word1.size() == word2.size()) { // Try replacement for (unsigned i = 0; i < word1.size(); ++i) { string w = word1; w[i] = word2[i]; if (w == word2) return true; } // Try transposing for (unsigned i = 1; i < word1.size(); ++i) { string w = word1; w[i] = word1[i-1]; w[i-1] = word1[i]; if (w == word2) return true; } } return false; } void solve (istream& in) { set allCores; map > similar; while (true) { string line; getline (in, line); if (line == "***") break; string word; istringstream lineIn (line); while (lineIn >> word) { string core = getCore(word); if (core != "" && allCores.count(core) == 0) { for (string other: allCores) { if (areSimilar(core, other)) { similar[core].insert(other); similar[other].insert(core); } } allCores.insert(core); } } } bool printed = false; for (string core: allCores) { set& similarCores = similar[core]; if (similarCores.size() > 0) { printed = true; cout << core << ":"; for (string other: similar[core]) { cout << ' ' << other; } cout << endl; } } if (!printed) { cout << "***" << endl; } } int main (int argc, char** argv) { if (argc > 1) { ifstream in (argv[1]); solve (in); } else solve (cin); }