// Finding all anagram groups in a given dictionary of words. #include #include #include #include #include #include #include #include typedef multimap > multimap_1; typedef multimap_1::value_type PS; typedef multimap_1::const_iterator PSi; struct PPS : pair { PPS() : pair(PSi(), PSi()) { } PPS(PSi p, PSi q) : pair(p, q) { } }; int main() { cout << "Anagram group finding program:\n" << "finds all anagram groups in a dictionary.\n\n" << "First, enter the name of the file containing\n" << "the dictionary: " << flush; string dictionary_name; cin >> dictionary_name; ifstream ifs(dictionary_name.c_str()); cout << "\nReading the dictionary ..." << flush; // Copy words from dictionary file to // a multimap: typedef istream_iterator string_input; multimap_1 word_pairs; for (string_input in(ifs); in != string_input(); ++in) { vector vstring = *in; sort(vstring.begin(), vstring.end()); word_pairs.insert(PS(string(vstring), *in)); } cout << "\nSearching " << word_pairs.size() << " words for anagram groups..." << flush; // Set up the map from anagram group sizes to lists of // groups of that size. typedef map, greater > map_1; map_1 groups; // Find all of the anagram groups and save their // positions in the groups map. cout << "\n\nThe anagram groups are: " << endl; PSi j = word_pairs.begin(), finis = word_pairs.end(), k; while (true) { // Make j point to the next anagram // group, or to the end of the multimap: j = adjacent_find(j,finis, not2(word_pairs.value_comp())); if (j == finis) break; // Find the end of the anagram group that begins at j: k = find_if(j, finis, bind1st(word_pairs.value_comp(), *j)); multimap_1::size_type n = 0; distance(j, k, n); if (n > 1) // Save the positions j and k delimiting the anagram // group in the list of groups of size n: groups[n].push_back(PPS(j, k)); // Prepare to continue search at position k: j = k; } // Iterate through the groups map to output the anagram // groups in order of decreasing size: map_1::const_iterator m; for (m = groups.begin(); m != groups.end(); ++m) { cout << "\n\nAnagram groups of size " << (*m).first << ":\n"; list::const_iterator l; for (l = (*m).second.begin(); l != (*m).second.end(); ++l) { cout << "\n "; j = (*l).first; // Beginning of the anagram group k = (*l).second; // End of the anagram group for (; j != k; ++j) cout << (*j).second << " "; cout << endl; } cout << endl; } }