- Data Structure
- Networking
- RDBMS
- Operating System
- Java
- MS Excel
- iOS
- HTML
- CSS
- Android
- Python
- C Programming
- C++
- C#
- MongoDB
- MySQL
- Javascript
- PHP
- Physics
- Chemistry
- Biology
- Mathematics
- English
- Economics
- Psychology
- Social Studies
- Fashion Studies
- Legal Studies
- Selected Reading
- UPSC IAS Exams Notes
- Developer's Best Practices
- Questions and Answers
- Effective Resume Writing
- HR Interview Questions
- Computer Glossary
- Who is Who
Given a sequence of words, print all anagrams together
Anagrams − An anagram is a word or a phrase formed by rearranging the alphabets of another word or phrase, usually once. Some examples of anagrams are given below −
Top - Pot
Silent - Listen
Post - Stop
Dog - God
Problem Statement
Given an array of words arr[]. For the given array print all the anagrams together.
Sample Example 1
Input
arr[] = {“star”, “god”, “vile”, “save”, “evil”, “care”, “arts”, “race”, “dog”, “vase”}
Output
arts star care race dog god evil vile save vase
Explanation
Anagrams in the given array are −
star - arts god - dog vile - evil save - vase care - race
Sample Example 2
Input
arr[] = {“thing”, “top”, “inlets”, “pot”, “opt”, “listen”, “night”}
Output
inlets listen night thing opt pot top
Explanation
Anagrams in the given array are −
thing - night top - pot - opt inlets - listen
Approach 1: Word Sorting
An approach to solve the problem is to sort the words in the arr[] and create a map where the key is the sorted word and values are the indices of the words having the same word after sorting. Print anagrams according to the indices stored in the original array.
Pseudocode
function anagrams(arr: vector of strings) -> set of sets of strings initialize an empty set of sets called 'res' create a copy of 'arr' called 'list' for each word 's' in 'list' sort the characters of 's' in ascending order initialize an empty unordered map called 'map' (key: string, value: vector of integers) for i = 0 to size of 'arr' - 1 add the index 'i' to the vector associated with the sorted word 'list[i]' in 'map' for each entry in 'map' initialize an empty set of strings called 'temp' for each index 'i' in entry's value vector add 'arr[i]' to 'temp' if size of 'temp' > 1 add 'temp' to 'res' return 'res'
Example: C++ Implementation
The following program prints all the anagrams together.
#include <iostream> #include <string> #include <vector> #include <unordered_map> #include <set> #include <algorithm> using namespace std; // Function to group anangrams together from the input array set<set<string>> anagrams(vector<string> const &arr){ set<set<string>> res; vector<string> list(arr); // Sorting words for (string &s : list){ sort(s.begin(), s.end()); } // Pushing sorted words into map along with indices unordered_map<string, vector<int>> map; for (int i = 0; i < arr.size(); i++){ map[list[i]].push_back(i); } for (auto itr : map){ set<string> temp; for (int i : itr.second){ temp.insert(arr[i]); } if (temp.size() > 1){ res.insert(temp); } } return res; } int main(){ vector<string> arr = {"thing", "top", "inlets", "pot", "opt", "listen", "night"}; set<set<string>> res = anagrams(arr); for (set<string> r : res){ for (string s : r){ cout << s << ' '; } cout << endl; } return 0; }
Output
inlets listen night thing opt pot top
Time Complexity − O(N*K logK) where N is the size of the input array and K is the average length of strings.
Space Complexity − O(N)
Approach 2: Using Multimap
For efficient grouping in the above code, we’ll use multimap. Maultimap offers efficient grouping, constant time insertion, fast lookup, collision handling and dynamic size.
Pseudocode
function anagrams(arr: vector of strings) -> set of sets of strings res = empty set of sets of strings list = copy of arr for each s in list sort the characters of s in ascending order map = empty unordered multimap of string to integer for i = 0 to size of arr - 1 insert the pair (list[i], i) into map itr = iterator pointing to the beginning of map while itr is not at the end of map temp = empty set of strings curr = copy of itr while itr is not at the end of map and itr's key is the same as curr's key add arr[itr's value] to temp move itr to the next element if size of temp > 1 add temp to res return res
Example: C++ Implementation
The following program prints all the anagrams together.
#include <iostream> #include <string> #include <vector> #include <unordered_map> #include <set> #include <algorithm> using namespace std; // Function to group anangrams together from the input array set<set<string>> anagrams(vector<string> const &arr){ set<set<string>> res; vector<string> list(arr); // Sorting words for (string &s : list){ sort(s.begin(), s.end()); } unordered_multimap<string, int> map; for (int i = 0; i < arr.size(); i++){ map.insert(make_pair(list[i], i)); } auto itr = map.begin(); while (itr != map.end()){ set<string> temp; for (auto curr = itr; itr != map.end() && itr->first == curr->first; itr++){ temp.insert(arr[itr->second]); } if (temp.size() > 1){ res.insert(temp); } } return res; } int main(){ vector<string> arr = {"thing", "top", "inlets", "pot", "opt", "listen", "night"}; set<set<string>> res = anagrams(arr); for (set<string> r : res){ for (string s : r){ cout << s << ' '; } cout << endl; } return 0; }
Output
inlets listen night thing opt pot top
Time Complexity − O(N*K logK + N + N*M) where N is the size of the input array and K is the average length of strings.
Space Complexity − O(N)
Conclusion
In conclusion, the provided C++ code efficiently groups anagrams from a given list of words based on their sorted representations. The solution provided are efficient and can be easily molded depending on particular use cases.