Friday, December 27, 2024
Google search engine
HomeData Modelling & AIGiven a sequence of words, print all anagrams together | Set 1

Given a sequence of words, print all anagrams together | Set 1

Given an array of words, print all anagrams together. For example, if the given array is {“cat”, “dog”, “tac”, “god”, “act”}, then output may be “cat tac act dog god”.

A simple method is to create a Hash Table. Calculate the hash value of each word in such a way that all anagrams have the same hash value. Populate the Hash Table with these hash values. Finally, print those words together with the same hash values. A simple hashing mechanism can be modulo sum of all characters. With modulo sum, two non-anagram words may have the same hash value. This can be handled by matching individual characters.

Following is another method to print all anagrams together. Take two auxiliary arrays, index array, and word array. Populate the word array with the given sequence of words. Sort each individual word of the word array. Finally, sort the word array and keep track of the corresponding indices. After sorting, all the anagrams cluster together. Use the index array to print the strings from the original array of strings.

Let us understand the steps with the following input Sequence of Words: 

"cat", "dog", "tac", "god", "act"

1) Create two auxiliary arrays index[] and words[]. Copy all given words to words[] and store the original indexes in index[] 

index[]:  0   1   2   3   4
words[]: cat dog tac god act

2) Sort individual words in words[]. Index array doesn’t change.

index[]:   0    1    2    3    4
words[]:  act  dgo  act  dgo  act

3) Sort the words array. Compare individual words using strcmp() to sort

index:     0    2    4    1    3
words[]:  act  act  act  dgo  dgo

4) All anagrams come together. But words are changed in the words array. To print the original words, take the index from the index array and use it in the original array. We get 

"cat tac act dog god"

Following are the implementations of the above algorithm. In the following program, an array of structure “Word” is used to store both index and word arrays. Dupray is another structure that stores an array of structure “Word”. 

C




// A C program to print all anagrams together
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
// structure for each word of duplicate array
struct Word {
    char* str; // to store word itself
    int index; // index of the word in the original array
};
 
// structure to represent duplicate array.
struct DupArray {
    struct Word* array; // Array of words
    int size; // Size of array
};
 
// Create a DupArray object that contains an array of Words
struct DupArray* createDupArray(char* str[], int size)
{
    // Allocate memory for dupArray and all members of it
    struct DupArray* dupArray
        = (struct DupArray*)malloc(sizeof(struct DupArray));
    dupArray->size = size;
    dupArray->array = (struct Word*)malloc(
        dupArray->size * sizeof(struct Word));
 
    // One by one copy words from the given wordArray to
    // dupArray
    int i;
    for (i = 0; i < size; ++i) {
        dupArray->array[i].index = i;
        dupArray->array[i].str
            = (char*)malloc(strlen(str[i]) + 1);
        strcpy(dupArray->array[i].str, str[i]);
    }
 
    return dupArray;
}
 
// Compare two characters. Used in qsort() for sorting an
// array of characters (Word)
int compChar(const void* a, const void* b)
{
    return *(char*)a - *(char*)b;
}
 
// Compare two words. Used in qsort() for sorting an array
// of words
int compStr(const void* a, const void* b)
{
    struct Word* a1 = (struct Word*)a;
    struct Word* b1 = (struct Word*)b;
    return strcmp(a1->str, b1->str);
}
 
// Given a list of words in wordArr[],
void printAnagramsTogether(char* wordArr[], int size)
{
    // Step 1: Create a copy of all words present in given
    // wordArr. The copy will also have original indexes of
    // words
    struct DupArray* dupArray
        = createDupArray(wordArr, size);
 
    // Step 2: Iterate through all words in dupArray and
    // sort individual words.
    int i;
    for (i = 0; i < size; ++i)
        qsort(dupArray->array[i].str,
              strlen(dupArray->array[i].str), sizeof(char),
              compChar);
 
    // Step 3: Now sort the array of words in dupArray
    qsort(dupArray->array, size, sizeof(dupArray->array[0]),
          compStr);
 
    // Step 4: Now all words in dupArray are together, but
    // these words are changed. Use the index member of word
    // struct to get the corresponding original word
    for (i = 0; i < size; ++i)
        printf("%s ", wordArr[dupArray->array[i].index]);
}
 
// Driver program to test above functions
int main()
{
    char* wordArr[] = { "cat", "dog", "tac", "god", "act" };
    int size = sizeof(wordArr) / sizeof(wordArr[0]);
    printAnagramsTogether(wordArr, size);
    return 0;
}


C++




// A C++ program to print all anagrams together
#include <bits/stdc++.h>
#include <string.h>
using namespace std;
 
// structure for each word of duplicate array
class Word {
public:
    char* str; // to store word itself
    int index; // index of the word in the original array
};
 
// structure to represent duplicate array.
class DupArray {
public:
    Word* array; // Array of words
    int size; // Size of array
};
 
// Create a DupArray object that contains an array of Words
DupArray* createDupArray(char* str[], int size)
{
    // Allocate memory for dupArray and all members of it
    DupArray* dupArray = new DupArray();
    dupArray->size = size;
    dupArray->array
        = new Word[(dupArray->size * sizeof(Word))];
 
    // One by one copy words from the given wordArray to
    // dupArray
    int i;
    for (i = 0; i < size; ++i) {
        dupArray->array[i].index = i;
        dupArray->array[i].str
            = new char[(strlen(str[i]) + 1)];
        strcpy(dupArray->array[i].str, str[i]);
    }
 
    return dupArray;
}
 
// Compare two characters. Used in qsort() for
// sorting an array of characters (Word)
int compChar(const void* a, const void* b)
{
    return *(char*)a - *(char*)b;
}
 
// Compare two words. Used in qsort()
// for sorting an array of words
int compStr(const void* a, const void* b)
{
    Word* a1 = (Word*)a;
    Word* b1 = (Word*)b;
    return strcmp(a1->str, b1->str);
}
 
// Given a list of words in wordArr[],
void printAnagramsTogether(char* wordArr[], int size)
{
    // Step 1: Create a copy of all words present in given
    // wordArr. The copy will also have original indexes of
    // words
    DupArray* dupArray = createDupArray(wordArr, size);
 
    // Step 2: Iterate through all words in dupArray and
    // sort individual words.
    int i;
    for (i = 0; i < size; ++i)
        qsort(dupArray->array[i].str,
              strlen(dupArray->array[i].str), sizeof(char),
              compChar);
 
    // Step 3: Now sort the array of words in dupArray
    qsort(dupArray->array, size, sizeof(dupArray->array[0]),
          compStr);
 
    // Step 4: Now all words in dupArray are together, but
    // these words are changed. Use the index member of word
    // struct to get the corresponding original word
    for (i = 0; i < size; ++i)
        cout << wordArr[dupArray->array[i].index] << " ";
}
 
// Driver program to test above functions
int main()
{
    char* wordArr[] = { "cat", "dog", "tac", "god", "act" };
    int size = sizeof(wordArr) / sizeof(wordArr[0]);
    printAnagramsTogether(wordArr, size);
    return 0;
}
 
// This is code is contributed by rathbhupendra


Java




// A Java program to print all anagrams together
import java.util.Arrays;
import java.util.Comparator;
public class GFG {
    // class for each word of duplicate array
    static class Word {
        String str; // to store word itself
        int index; // index of the word in the
        // original array
 
        // constructor
        Word(String str, int index)
        {
            this.str = str;
            this.index = index;
        }
    }
 
    // class to represent duplicate array.
    static class DupArray {
        Word[] array; // Array of words
        int size; // Size of array
 
        // constructor
        public DupArray(String str[], int size)
        {
            this.size = size;
            array = new Word[size];
 
            // One by one copy words from the
            // given wordArray to dupArray
            int i;
            for (i = 0; i < size; ++i) {
                // create a word Object with the
                // str[i] as str and index as i
                array[i] = new Word(str[i], i);
            }
        }
    }
 
    // Compare two words. Used in Arrays.sort() for
    // sorting an array of words
    static class compStr implements Comparator<Word> {
        public int compare(Word a, Word b)
        {
            return a.str.compareTo(b.str);
        }
    }
 
    // Given a list of words in wordArr[],
    static void printAnagramsTogether(String wordArr[],
                                      int size)
    {
        // Step 1: Create a copy of all words present
        // in given wordArr. The copy will also have
        // original indexes of words
        DupArray dupArray = new DupArray(wordArr, size);
 
        // Step 2: Iterate through all words in
        // dupArray and sort individual words.
        int i;
        for (i = 0; i < size; ++i) {
            char[] char_arr
                = dupArray.array[i].str.toCharArray();
            Arrays.sort(char_arr);
            dupArray.array[i].str = new String(char_arr);
        }
 
        // Step 3: Now sort the array of words in
        // dupArray
        Arrays.sort(dupArray.array, new compStr());
 
        // Step 4: Now all words in dupArray are together,
        // but these words are changed. Use the index
        // member of word struct to get the corresponding
        // original word
        for (i = 0; i < size; ++i)
            System.out.print(
                wordArr[dupArray.array[i].index] + " ");
    }
 
    // Driver program to test above functions
    public static void main(String args[])
    {
        String wordArr[]
            = { "cat", "dog", "tac", "god", "act" };
        int size = wordArr.length;
        printAnagramsTogether(wordArr, size);
    }
}
// This code is contributed by Sumit Ghosh


Python




# A Python program to print all anagrams together
 
# structure for each word of duplicate array
 
 
class Word(object):
    def __init__(self, string, index):
        self.string = string
        self.index = index
 
# Create a DupArray object that contains an array
# of Words
 
 
def createDupArray(string, size):
    dupArray = []
 
    # One by one copy words from the given wordArray
    # to dupArray
    for i in xrange(size):
        dupArray.append(Word(string[i], i))
 
    return dupArray
 
# Given a list of words in wordArr[]
 
 
def printAnagramsTogether(wordArr, size):
    # Step 1: Create a copy of all words present in
    # given wordArr.
    # The copy will also have original indexes of words
    dupArray = createDupArray(wordArr, size)
 
    # Step 2: Iterate through all words in dupArray and sort
    # individual words.
    for i in xrange(size):
        dupArray[i].string = ''.join(sorted(dupArray[i].string))
 
    # Step 3: Now sort the array of words in dupArray
    dupArray = sorted(dupArray, key=lambda k: k.string)
 
    # Step 4: Now all words in dupArray are together, but
    # these words are changed. Use the index member of word
    # struct to get the corresponding original word
    for word in dupArray:
        print wordArr[word.index],
 
 
# Driver program
wordArr = ["cat", "dog", "tac", "god", "act"]
size = len(wordArr)
printAnagramsTogether(wordArr, size)
 
# This code is contributed by BHAVYA JAIN


C#




// A C# program to print all anagrams together
using System;
using System.Linq;
 
// structure for each word of duplicate array
class Word {
  public string Str; // to store word itself
  public int Index; // index of the word in the original array
}
 
// structure to represent duplicate array.
class DupArray {
  public Word[] Array; // Array of words
  public int Size; // Size of array
}
 
public class GFG {
 
  // Create a DupArray object that contains an array of Words
  static DupArray CreateDupArray(string[] str, int size)
  {
    // Allocate memory for dupArray and all members of it
    var dupArray = new DupArray();
    dupArray.Size = size;
    dupArray.Array = new Word[dupArray.Size];
 
    // One by one copy words from the given wordArray to
    // dupArray
    for (var i = 0; i < size; i++) {
      dupArray.Array[i] = new Word();
      dupArray.Array[i].Index = i;
      dupArray.Array[i].Str = str[i];
    }
 
    return dupArray;
  }
 
  // Compare two words. Used in OrderBy()
  // for sorting an array of words
  static int CompStr(Word a, Word b)
  {
    return string.Compare(new string(a.Str.OrderBy(c => c).ToArray()), new string(b.Str.OrderBy(c => c).ToArray()));
  }
 
  // Given a list of words in wordArr[],
  static void PrintAnagramsTogether(string[] wordArr, int size)
  {
    // Step 1: Create a copy of all words present in given
    // wordArr. The copy will also have original indexes of
    // words
    var dupArray = CreateDupArray(wordArr, size);
 
    // Step 2: Iterate through all words in
    // dupArray and sort individual words .
    // Step 3: Now sort the array of words in dupArray
    Array.Sort(dupArray.Array, CompStr);
 
    // Step 3: Now all words in dupArray are together, but
    // these words are changed. Use the index member of word
    // struct to get the corresponding original word
    foreach (var word in dupArray.Array)
    {
      Console.Write(wordArr[word.Index] + " ");
    }
  }
 
  // Driver program to test above functions
  static public void Main(string[] args)
  {
    var wordArr = new string[] { "cat", "dog", "tac", "god", "act" };
    var size = wordArr.Length;
    PrintAnagramsTogether(wordArr, size);
  }
}
 
// This code is contributed by Prasad Kandekar(prasad264)


Javascript




// A JavaScript program to print all anagrams together
 
// structure for each word of duplicate array
class Word {
    constructor(string, index) {
        this.string = string;
        this.index = index;
    }
}
 
// Create a DupArray object that contains an array
// of Words
function createDupArray(string, size) {
    let dupArray = [];
 
    // One by one copy words from the given wordArray
    // to dupArray
    for (let i = 0; i < size; i++) {
        dupArray.push(new Word(string[i], i));
    }
 
    return dupArray;
}
 
// Given a list of words in wordArr[]
function printAnagramsTogether(wordArr, size) {
    // Step 1: Create a copy of all words present in
    // given wordArr.
    // The copy will also have original indexes of words
    let dupArray = createDupArray(wordArr, size);
 
    // Step 2: Iterate through all words in dupArray and sort
    // individual words.
    for (let i = 0; i < size; i++) {
        dupArray[i].string = dupArray[i].string.split("").sort().join("");
    }
 
    // Step 3: Now sort the array of words in dupArray
    dupArray = dupArray.sort((a, b) => a.string.localeCompare(b.string));
 
    // Step 4: Now all words in dupArray are together, but
    // these words are changed. Use the index member of word
    // struct to get the corresponding original word
    for (let word of dupArray) {
        console.log(wordArr[word.index]);
    }
}
 
// Driver program
let wordArr = ["cat", "dog", "tac", "god", "act"];
let size = wordArr.length;
printAnagramsTogether(wordArr, size);
 
// This code is contributed by prasad264


Output: 

cat tac act dog god 

Time Complexity: Let there be N-words and each word has a maximum of M characters. The upper bound is O(NMLogM + MNLogN). 
Step 2 takes O(NMLogM) time. Sorting a word takes maximum O(MLogM) time. So sorting N-words takes O(NMLogM) time. step 3 takes O(MNLogN) Sorting array of words takes NLogN comparisons. A comparison may take maximum O(M) time. So time to sort an array of words will be O(MNLogN).
 

Space complexity :- O(N*M)

Using vector of pair :

The problem can easily be solved with the use of a vector of pairs. The pair will be of string and int. The string will require to store the input string and int will require to store their respective indexes. 

here is the implementation of the above approach:

C




#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
struct Pair {
    char word[100];
    int index;
};
 
void createDuplicateArray(struct Pair dupArray[],
                          char* wordAr[], int size)
{
    for (int i = 0; i < size; i++) {
        strcpy(dupArray[i].word, wordAr[i]);
        dupArray[i].index = i;
    }
}
 
void printAnagramsTogether(char* wordArr[], int size)
{
    struct Pair dupArray[size];
    createDuplicateArray(dupArray, wordArr, size);
 
    int i;
    for (i = 0; i < size; ++i) {
        int len = strlen(dupArray[i].word);
        qsort(dupArray[i].word, len, sizeof(char),
              (__compar_fn_t)strcmp);
    }
 
    qsort(dupArray, size, sizeof(struct Pair),
          (__compar_fn_t)strcmp);
 
    for (i = 0; i < size; ++i) {
        printf("%s ", wordArr[dupArray[i].index]);
    }
}
 
int main()
{
    char* wordArr[] = { "cat", "dog", "tac", "god", "act" };
    int size = sizeof(wordArr) / sizeof(wordArr[0]);
    printAnagramsTogether(wordArr, size);
    return 0;
}


C++




#include <bits/stdc++.h>
#include <strings.h>
using namespace std;
 
void createDuplicateArray(
    vector<pair<string, int> >& dupArray,
    vector<string>& wordAr, int size)
{
    for (int i = 0; i < size; i++) {
        dupArray.push_back(make_pair(wordAr[i], i));
        // pair.first contains the input words and
        // pair.second contains its index
    }
}
 
void printAnagramsTogether(vector<string>& wordArr,
                           int size)
{
 
    vector<pair<string, int> >
        dupArray; // dupArray to store the word-index pair
    createDuplicateArray(
        dupArray, wordArr,
        size); // making copy of all the words and their
               // respective index
 
    // Iterate through all words in dupArray and sort
    // characters in each word.
    int i;
    for (i = 0; i < size; ++i) {
        sort(dupArray[i].first.begin(),
             dupArray[i].first.end());
    }
 
    // now sort the whole vector to get the identical words
    // together
    sort(dupArray.begin(), dupArray.end());
 
    // now all the identical words are together but we have
    // lost the original form of string
    // so through index stored in the word-index pair fetch
    // the original word from main input
    for (i = 0; i < size; ++i)
        cout << wordArr[dupArray[i].second] << " ";
}
 
int main()
{
    vector<string> wordArr
        = { "cat", "dog", "tac", "god", "act" };
    printAnagramsTogether(wordArr, wordArr.size());
    return 0;
}


Java




import java.io.*;
import java.util.*;
public class Main {
 
    static class Pair implements Comparable<Pair> {
        String x;
        int y;
        public Pair(String x, int y)
        {
            this.x = x;
            this.y = y;
        }
        public int compareTo(Pair o)
        {
            return this.x.compareTo(o.x);
        }
    }
    static ArrayList<Pair>
    createDuplicateArray(String[] wordArr, int size)
    {
        ArrayList<Pair> dupArray = new ArrayList<Pair>();
        for (int i = 0; i < size; i++) {
            Pair p = new Pair(wordArr[i], i);
            dupArray.add(p);
           
            // pair.first contains the input words and
            // pair.second contains its index
        }
        return dupArray;
    }
    static void printAnagramsTogether(String[] wordArr,
                                      int size)
    {
 
        ArrayList<Pair> dupArray = new ArrayList<Pair>();
       
        ; // dupArray to store the word-index pair
        dupArray = createDuplicateArray(
            wordArr, size); // making copy of all the words
                            // and their respective index
 
        // Iterate through all words in dupArray and sort
        // characters in each word.
        for (int i = 0; i < size; ++i) {
            Pair e = dupArray.get(i);
            char[] arr = e.x.toCharArray();
            Arrays.sort(arr);
            String x = String.valueOf(arr);
            Pair p = new Pair(x, e.y);
            dupArray.set(i, p);
        }
       
        // now sort the whole vector to get the identical
        // words together
        Collections.sort(dupArray);
       
        // now all the identical words are together but we
        // have lost the original form of string so through
        // index stored in the word-index pair fetch the
        // original word from main input
        for (int i = 0; i < size; ++i)
            System.out.print(wordArr[dupArray.get(i).y]
                             + " ");
    }
 
    public static void main(String[] args)
    {
        String[] wordArr
            = { "cat", "dog", "tac", "god", "act" };
        printAnagramsTogether(wordArr, wordArr.length);
    }
}
 
// This code is contributed by garg28harsh.


Python3




from typing import List, Tuple
def create_duplicate_array(wordAr: List[str]) -> List[Tuple[str, int]]:
    dup_array = []
    # Iterate through the original list of words
    for i, word in enumerate(wordAr):
        # Append each word along with its index in the original list to the duplicate array
        dup_array.append((word, i))
    return dup_array
 
# Function to print out all the words that are anagrams of each other next to each other
def print_anagrams_together(wordArr: List[str]):
    # Create a duplicate array containing the words and their indices
    dup_array = create_duplicate_array(wordArr)
 
    # Iterate through the duplicate array and sort each word alphabetically
    for i in range(len(wordArr)):
        dup_array[i] = (sorted(dup_array[i][0]), dup_array[i][1])
    # Sort the duplicate array based on the sorted words
    dup_array.sort()
 
    # Iterate through the sorted duplicate array and print out the original words using their indices
    for i in range(len(wordArr)):
        print(wordArr[dup_array[i][1]], end=' ')
 
# Test the function with an example list of words
wordArr = ["cat", "dog", "tac", "god", "act"]
print_anagrams_together(wordArr)
 
# This code is contributed by Shivam Tiwari


C#




using System;
using System.Collections.Generic;
using System.Linq;
 
public class GFG {
    class Pair : IComparable<Pair> {
        public string x;
        public int y;
 
        public Pair(string x, int y)
        {
            this.x = x;
            this.y = y;
        }
 
        public int CompareTo(Pair other)
        {
            return this.x.CompareTo(other.x);
        }
    }
 
    static List<Pair> CreateDuplicateArray(string[] wordArr,
                                           int size)
    {
        List<Pair> dupArray = new List<Pair>();
        for (int i = 0; i < size; i++) {
            Pair p = new Pair(wordArr[i], i);
            dupArray.Add(p);
 
            // pair.first contains the input words and
            // pair.second contains its index
        }
        return dupArray;
    }
 
    static void PrintAnagramsTogether(string[] wordArr,
                                      int size)
    {
 
        // dupArray to store the word-index pair
        List<Pair> dupArray
            = CreateDuplicateArray(wordArr, size);
        // making copy of all the words
        // and their respective index
 
        // Iterate through all words in dupArray and sort
        // characters in each word.
        for (int i = 0; i < size; i++) {
            Pair e = dupArray[i];
            char[] arr = e.x.ToCharArray();
            Array.Sort(arr);
            string x = new string(arr);
            Pair p = new Pair(x, e.y);
            dupArray[i] = p;
        }
 
        // now sort the whole vector to get the identical
        // words together
        dupArray.Sort();
 
        // now all the identical words are together but we
        // have lost the original form of string so through
        // index stored in the word-index pair fetch the
        // original word from main input
        for (int i = 0; i < size; i++) {
            Console.Write(wordArr[dupArray[i].y] + " ");
        }
    }
 
    static public void Main(string[] args)
    {
        string[] wordArr
            = { "cat", "dog", "tac", "god", "act" };
        PrintAnagramsTogether(wordArr, wordArr.Length);
    }
}
 
// This code is contributed by Prasad Kandekar(prasad264)


Javascript




// Array to store the words
var wordArr = [ "cat", "dog", "tac", "god", "act" ];
 
// Function to create an array of pairs where each
// pair contains the word and its index in the original array
function createDuplicateArray(wordArr, size) {
  var dupArray = [];
  for (var i = 0; i < size; i++) {
    var pair = {
      x: wordArr[i],
      y: i
    };
    dupArray.push(pair);
  }
  return dupArray;
}
 
// Function to print all anagrams together
function printAnagramsTogether(wordArr, size) {
  var dupArray = createDuplicateArray(wordArr, size);
 
  // Sort each word in dupArray
  for (var i = 0; i < size; i++) {
    var word = dupArray[i].x;
    word = word.split("").sort().join("");
    dupArray[i].x = word;
  }
 
  // Sort the dupArray based on the sorted words
  dupArray.sort(function(a, b) {
    return a.x.localeCompare(b.x);
  });
 
  // Print the original words based on the indices
  // stored in the dupArray
  for (var i = 0; i < size; i++) {
    console.log(wordArr[dupArray[i].y]);
  }
}
 
// Call the printAnagramsTogether function
printAnagramsTogether(wordArr, wordArr.length);
 
// This code is contributed by Shivam Tiwari


Output

cat tac act dog god 

Time complexity

Let there be N-words and each word has a maximum of M characters.

 O(NMLogM + MNLogN). 

Space complexity :- O(N)

Using hashmap
Here, we first sort each word, use the sorted word as a key and then put an original word on a map. The value of the map will be a list containing all the words which have the same word after sorting. 
Lastly, we will print all values from the hashmap where the size of values will be greater than 1.

C++




// C++ program to print anagrams
// together using dictionary
#include <bits/stdc++.h>
using namespace std;
 
void printAnagrams(string arr[], int size)
{
    unordered_map<string, vector<string> > map;
 
    // Loop over all words
    for (int i = 0; i < size; i++) {
 
        // Convert to char array, sort and
        // then re-convert to string
        string word = arr[i];
        char letters[word.size() + 1];
        strcpy(letters, word.c_str());
        sort(letters, letters + word.size() + 1);
        string newWord = "";
        for (int i = 0; i < word.size() + 1; i++) {
            newWord += letters[i];
        }
 
        // Calculate hashcode of string
        // after sorting
        if (map.find(newWord) != map.end()) {
            map[newWord].push_back(word);
        }
        else {
 
            // This is the first time we are
            // adding a word for a specific
            // hashcode
            vector<string> words;
            words.push_back(word);
            map[newWord] = words;
        }
    }
 
    // Print all the values where size is > 1
    // If you want to print non-anagrams,
    // just print the values having size = 1
    unordered_map<string, vector<string> >::iterator it;
    for (it = map.begin(); it != map.end(); it++) {
        vector<string> values = map[it->first];
        if (values.size() > 1) {
            cout << "[";
            for (int i = 0; i < values.size() - 1; i++) {
                cout << values[i] << ", ";
            }
            cout << values[values.size() - 1];
            cout << "]";
        }
    }
}
 
// Driver code
int main()
{
    string arr[] = { "cat", "dog", "tac", "god", "act" };
    int size = sizeof(arr) / sizeof(arr[0]);
 
    printAnagrams(arr, size);
 
    return 0;
}
 
// This code is contributed by Ankit Garg


Java




// Java program to print anagrams
// together using dictionary
import java.util.*;
 
public class FindAnagrams {
 
    private static void printAnagrams(String arr[])
    {
        HashMap<String, List<String> > map
            = new HashMap<>();
 
        // loop over all words
        for (int i = 0; i < arr.length; i++) {
 
            // convert to char array, sort and
            // then re-convert to string
            String word = arr[i];
            char[] letters = word.toCharArray();
            Arrays.sort(letters);
            String newWord = new String(letters);
 
            // calculate hashcode of string
            // after sorting
            if (map.containsKey(newWord)) {
 
                map.get(newWord).add(word);
            }
            else {
 
                // This is the first time we are
                // adding a word for a specific
                // hashcode
                List<String> words = new ArrayList<>();
                words.add(word);
                map.put(newWord, words);
            }
        }
 
        // print all the values where size is > 1
        // If you want to print non-anagrams,
        // just print the values having size = 1
        for (String s : map.keySet()) {
            List<String> values = map.get(s);
            if (values.size() > 1) {
                System.out.print(values);
            }
        }
    }
 
    public static void main(String[] args)
    {
 
        // Driver program
        String arr[]
            = { "cat", "dog", "tac", "god", "act" };
        printAnagrams(arr);
    }
}


Python3




from collections import defaultdict
 
 
def printAnagramsTogether(words):
    groupedWords = defaultdict(list)
 
    # Put all anagram words together in a dictionary
    # where key is sorted word
    for word in words:
        groupedWords["".join(sorted(word))].append(word)
 
    # Print all anagrams together
    for group in groupedWords.values():
        print(" ".join(group))
 
 
if __name__ == "__main__":
    arr = ["cat", "dog", "tac", "god", "act"]
    printAnagramsTogether(arr)


C#




// C# program to print anagrams
// together using dictionary
using System;
using System.Collections.Generic;
 
class GFG {
    private static void printAnagrams(String[] arr)
    {
        Dictionary<String, List<String> > map
            = new Dictionary<String, List<String> >();
 
        // loop over all words
        for (int i = 0; i < arr.Length; i++) {
 
            // convert to char array, sort and
            // then re-convert to string
            String word = arr[i];
            char[] letters = word.ToCharArray();
            Array.Sort(letters);
            String newWord = new String(letters);
 
            // calculate hashcode of string
            // after sorting
            if (map.ContainsKey(newWord)) {
                map[newWord].Add(word);
            }
            else {
 
                // This is the first time we are
                // adding a word for a specific
                // hashcode
                List<String> words = new List<String>();
                words.Add(word);
                map.Add(newWord, words);
            }
        }
 
        // print all the values where size is > 1
        // If you want to print non-anagrams,
        // just print the values having size = 1
        List<String> value = new List<String>();
        foreach(KeyValuePair<String, List<String> > entry in
                    map)
        {
            value.Add(entry.Key);
        }
        int k = 0;
        foreach(KeyValuePair<String, List<String> > entry in
                    map)
        {
            List<String> values = map[value[k++]];
            if (values.Count > 1) {
                Console.Write("[");
                int len = 1;
                foreach(String s in values)
                {
                    Console.Write(s);
                    if (len++ < values.Count)
                        Console.Write(", ");
                }
                Console.Write("]");
            }
        }
    }
 
    // Driver Code
    public static void Main(String[] args)
    {
        String[] arr
            = { "cat", "dog", "tac", "god", "act" };
        printAnagrams(arr);
    }
}
 
// This code is contributed by Princi Singh


Javascript




// JavaScript program to print anagrams
// together using dictionary
 
function printAnagrams(arr) {
 
  const map = {};
 
  // loop over all words
  for (let i = 0; i < arr.length; i++) {
 
    // convert to char array, sort and
    // then re-convert to string
    let word = arr[i];
    let letters = word.split("");
    letters.sort();
    let newWord = letters.join("");
 
    // calculate hashcode of string
    // after sorting
    if (map[newWord]) {
 
      map[newWord].push(word);
 
    } else {
 
      // This is the first time we are
      // adding a word for a specific
      // hashcode
      const words = [];
      words.push(word);
      map[newWord] = words;
    }
  }
 
  // print all the values where size is > 1
  // If you want to print non-anagrams,
  // just print the values having size = 1
  for (const s in map) {
    const values = map[s];
    if (values.length > 1) {
      console.log(values);
    }
  }
}
 
// Driver program
const arr = ["cat", "dog", "tac", "god", "act"];
printAnagrams(arr);
// This code is contributed By Shivam Tiwari


Output

[dog, god][cat, tac, act]

Time Complexity :  O(N x M x logM + N). 

Auxiliary space: O(M x N). 

HashMap with O(NM) Solution
In the previous approach, we were sorting every string in order to maintain a similar key, but that cost extra time in this approach will take the advantage of another hashmap to maintain the frequency of the characters which will generate the same hash function for different string having same frequency of characters.
Here, we will take HashMap<HashMap, ArrayList>, the inner hashmap will count the frequency of the characters of each string and the outer HashMap will check whether that hashmap is present or not if present then it will add that string to the corresponding list. 

C++




// C++ code to print all anagrams together
#include <bits/stdc++.h>
using namespace std;
 
void solver(vector<string> my_list)
{
     
    // Inner hashmap counts frequency
    // of characters in a string.
    // Outer hashmap for if same
    // frequency characters are present in
    // in a string then it will add it to
    // the vector.
    map<map<char, int>, vector<string>> my_map;
     
    // Loop over all words
    for(string str : my_list)
    {
         
        // Counting the frequency of the
        // characters present in a string
        map<char, int> temp_map;
        vector<string> temp_my_list;
        for(int i = 0; i < str.length(); ++i)
        {
            ++temp_map[str[i]];
        }
         
        // If the same frequency of characters
        // are already present then add that
        // string into that arraylist otherwise
        // created a new arraylist and add that
        // string
        auto it = my_map.find(temp_map);
        if (it != my_map.end())
        {
            it->second.push_back(str);
        }
        else
        {
            temp_my_list.push_back(str);
            my_map.insert({ temp_map, temp_my_list });
        }
    }
     
    // Stores the result in a vector
    vector<vector<string>> result;
 
    for(auto it = my_map.begin();
             it != my_map.end(); ++it)
    {
        result.push_back(it->second);
    }
 
    for(int i = 0; i < result.size(); ++i)
    {
          cout << "[";
        for(int j = 0; j < result[i].size(); ++j)
        {
            cout << result[i][j] << ", ";
        }
          cout << "]";
    }
}
 
// Driver code
int main()
{
    vector<string> my_list = { "cat", "dog", "ogd",
                               "god", "atc" };
    solver(my_list);
    return 0;
}
 
// This code is contributed by
// Apurba Kumar Gorai(coolapurba05)


Java




// Java code tp print all anagrams together
import java.util.ArrayList;
import java.util.HashMap;
 
public class FindAnagrams {
 
    private static ArrayList<ArrayList<String> >
    solver(
        ArrayList<String> list)
    {
 
        // Inner hashmap counts frequency
        // of characters in a string.
        // Outer hashmap for if same
        // frequency characters are present in
        // in a string then it will add it to
        // the arraylist.
        HashMap<HashMap<Character, Integer>,
                ArrayList<String> >
            map = new HashMap<HashMap<Character, Integer>,
                              ArrayList<String> >();
        for (String str : list) {
            HashMap<Character, Integer>
                tempMap = new HashMap<Character, Integer>();
 
            // Counting the frequency of the
            // characters present in a string
            for (int i = 0; i < str.length(); i++) {
                if (tempMap.containsKey(str.charAt(i))) {
                    int x = tempMap.get(str.charAt(i));
                    tempMap.put(str.charAt(i), ++x);
                }
                else {
                    tempMap.put(str.charAt(i), 1);
                }
            }
 
            // If the same frequency of characters
            // are already present then add that
            // string into that arraylist otherwise
            // created a new arraylist and add that string
            if (map.containsKey(tempMap))
                map.get(tempMap).add(str);
            else {
                ArrayList<String>
                    tempList = new ArrayList<String>();
                tempList.add(str);
                map.put(tempMap, tempList);
            }
        }
 
        // Stores the result in a arraylist
        ArrayList<ArrayList<String> >
            result = new ArrayList<>();
        for (HashMap<Character, Integer>
                 temp : map.keySet())
            result.add(map.get(temp));
        return result;
    }
 
    // Drivers Method
    public static void main(String[] args)
    {
        ArrayList<String> list = new ArrayList<>();
        list.add("cat");
        list.add("dog");
        list.add("ogd");
        list.add("god");
        list.add("atc");
 
        System.out.println(solver(list));
    }
}
 
// This code is contributed by Arijit Basu(ArijitXfx)


Python3




# Python code to print all anagrams together
from collections import Counter, defaultdict
user_input = ["cat", "dog", "tac", "edoc", "god", "tacact",
              "act", "code", "deno", "node", "ocde", "done", "catcat"]
 
 
def solve(words: list) -> list:
    # defaultdict will create a new list if the key is not found in the dictionary
    m = defaultdict(list)
 
    # loop over all the words
    for word in words:
        # Counter('cat') :
        #    counts the frequency of the characters present in a string
        #    >>> Counter({'c': 1, 'a': 1, 't': 1})
 
        # frozenset(dict(Counter('cat')).items()) :
        #    frozenset takes an iterable object as input and makes them immutable.
        #    So that hash(frozenset(Counter('cat'))) is equal to
        #   hash of other 'cat' anagrams
        #    >>> frozenset({('c', 1), ('a', 1), ('t', 1)})
        m[frozenset(dict(Counter(word)).items())].append(word)
    return [v for k, v in m.items()]
 
 
print(solve(user_input))
 
# This code is contributed by
# Rohan Kumar(@r0hnx)


C#




// C# code to print all anagrams together
using System;
using System.Collections.Generic;
using System.Linq;
 
class Program {
    static void Main(string[] args)
    {
        List<string> myList = new List<string>() {
            "cat", "dog", "ogd", "god", "atc"
        };
        Solver(myList);
    }
 
    static void Solver(List<string> myList)
    {
        // Inner dictionary counts frequency
        // of characters in a string.
        // Outer dictionary for if same
        // frequency characters are present in
        // in a string then it will add it to
        // the list.
        Dictionary<string, List<string> > myMap
            = new Dictionary<string, List<string> >();
 
        // Loop over all words
        foreach(string str in myList)
        {
            // Sorting the string to group anagrams together
            char[] arr = str.ToCharArray();
            Array.Sort(arr);
            string sortedStr = new string(arr);
 
            // If the same frequency of characters
            // are already present then add that
            // string into that list otherwise
            // create a new list and add that
            // string
            if (myMap.ContainsKey(sortedStr)) {
                myMap[sortedStr].Add(str);
            }
            else {
                List<string> tempList
                    = new List<string>() { str };
                myMap.Add(sortedStr, tempList);
            }
        }
 
        // Stores the result in a list
        List<List<string> > result
            = new List<List<string> >();
 
        foreach(KeyValuePair<string, List<string> > kvp in
                    myMap)
        {
            result.Add(kvp.Value);
        }
 
        foreach(List<string> list in result)
        {
            Console.Write("[");
            Console.Write(String.Join(", ", list));
            Console.Write("] ");
        }
        Console.WriteLine();
    }
}
 
// This code is contributed by rutikbhosale


Javascript




// Javascript program for the above approach
 
let user_input = ["cat", "dog", "tac", "edoc", "god", "tacact",
              "act", "code", "deno", "node", "ocde", "done", "catcat"];
 
function solve(words) {
    // create a new map if the key is not found in the dictionary
    let m = new Map();
         
    // loop over all the words
    for (let word of words) {
        let charCount = new Map();
        for (let char of word) {
            charCount.set(char, (charCount.get(char) || 0) + 1);
        }
        let key = JSON.stringify([...charCount.entries()].sort());
        let values = m.get(key) || [];
        values.push(word);
        m.set(key, values);
    }
    return [...m.values()];
}
 
console.log(solve(user_input));
 
// This code is contributed by codebraxnzt


Output

[cat, atc, ][dog, ogd, god, ]

Time Complexity: Let there be N-words and each word has a maximum of M characters. The upper bound is O(NM). 
Space Complexity: Let there be N-words and each word has maximum M characters, therefore max. storage space for each word with at max. M characters will be O(M), therefore for max N-words, it will be O(N*M). Therefore, the upper bound is O(NM).

This article is contributed by Aarti_Rathi  and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the neveropen main page and help other Geeks.
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.

Given a sequence of words, print all anagrams together | Set 2 
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
 

Feeling lost in the world of random DSA topics, wasting time without progress? It’s time for a change! Join our DSA course, where we’ll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!

RELATED ARTICLES

Most Popular

Recent Comments