Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*******************************************************************************
- * Name : anagramfinder.cpp
- * Author : Christopher Tan
- * Version : 1.0
- * Date : 10/25/19
- * Description : Anagram finder.
- * Pledge : I pledge my honor that I have abided by the Stevens Honor System.
- ******************************************************************************/
- #include <iostream>
- #include <fstream>
- #include <string>
- #include <cctype>
- #include <map>
- #include <set>
- #include <vector>
- #include <bits/stdc++.h>
- #include <stdio.h>
- #include <errno.h>
- using namespace std;
- int main(int argc, char* argv[]) {
- ifstream fs;
- fs.open(argv[1]);
- if (argc != 2) {
- cerr << "Usage: ./anagramfinder <dictionary file>" << endl;
- return 1;
- }
- FILE * pFile;
- pFile = fopen (argv[1] , "r");
- if (pFile == NULL) {
- cerr << "Error: File '" << argv[1] << "' not found." << endl;
- return 1;
- }
- ifstream file(argv[1]);
- // sort the output so the words in each group are alphabetized as well as the overall result.
- // map similarly should store key in a sorted fashion.
- map<string, vector<string>> anagrams_map;
- string word;
- // track the keyset corresponding to the largest group(s) of anagrams
- set<string> result_keys;
- long unsigned largest_group_size = 0;
- while (file >> word) {
- // process just the words containing upper case letters A through Z and
- // lowercase letters a through z.
- bool is_valid_word = all_of(begin(word), end(word), [](char c) { return isalpha(c); });
- if (not is_valid_word) {
- continue;
- }
- // when finding anagrams, take a case-insenstive approach
- // strategy here is to use the sorted, lowercase version of a word as the "key" in our map.
- string key = word;
- transform(key.begin(), key.end(), key.begin(), [](unsigned char c) { return tolower(c); } );
- sort(key.begin(), key.end());
- // grab the group of anagrams for this word so far.
- vector<string> &anagrams = anagrams_map[key];
- anagrams.emplace_back(word);
- if (result_keys.empty()) {
- result_keys.emplace(key);
- largest_group_size = 1;
- } else {
- if (anagrams.size() < largest_group_size) {
- // not big enough.
- continue;
- } else if (anagrams.size() == largest_group_size) {
- // keep track of this anagram key
- result_keys.emplace(key);
- } else {
- // this anagram key starts a new biggest group
- set<string> new_anagram_result_keys;
- new_anagram_result_keys.emplace(key);
- // get rid of the existing keyset and
- // start a new keyset with this key.
- //
- // ie. anagrams_map currently:
- // {act -> {tac, act},
- // {abe -> {bea, bae},
- // {deer -> {reed, eder}}
- //
- // result_key_set currently:
- // {act, abe, deer} since each group has size 2.
- //
- // we process a new word: cat.
- // {act -> {tac, act, cat},
- // {abe -> {bea, bae},
- // {deer -> {reed, eder}}
- //
- // our new result key set should just be
- // {act} of size 3.
- //
- result_keys = move(new_anagram_result_keys);
- largest_group_size = anagrams.size();
- }
- }
- }
- if (argc != 2) {
- cerr << "Usage: ./anagramfinder <dictionary file>" << endl;
- return 1;
- }
- if (largest_group_size < 2) {
- cout << "No anagrams found." << endl;
- return 0;
- }
- cout << "Max anagrams: " << largest_group_size << endl;
- vector<vector<string>> output;
- for (const auto &key : result_keys) {
- auto &group = anagrams_map[key];
- // sort the words in this group of anagrams
- sort(group.begin(), group.end());
- output.emplace_back(group);
- }
- // sort the overall groups
- sort(output.begin(), output.end(), [](const vector<string> &a, const vector<string> &b) {
- return a[0] < b[0];
- });
- for (unsigned int i = 0; i < output.size(); ++i) {
- const auto &group = output[i];
- if (i != 0) {
- cout << "" << endl;
- }
- for (const auto &word : group) {
- cout << word << endl;
- }
- }
- fs.close();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement