http://www.ideserve.co.in/learn/anagram-grouping-in-a-sequence-using-trie
Given a sequence of words, print all anagrams together, For example, if given word sequence is ["god","act","tic","tac","dog","cat"] then output of the program should be -
god, dog
act, tac, cat
tic
Order of groups can be different but group members should be same.
The basic idea used is simple. Insert the individual words of the sequence in a trie but before inserting a word sort it according to the characters. This way, when anagrams are inserted into a trie, their path from root node to leaf node would be exactly the same and if we store the indices of the words in given sequence at leaf node, then we would be able to print all anagrams in grouped manner. The idea is illustrated in below trie diagram.
http://www.ideserve.co.in/learn/anagram-grouping-in-a-sequence-using-trie
Given a sequence of words, print all anagrams together, For example, if given word sequence is ["god","act","tic","tac","dog","cat"] then output of the program should be -
god, dog
act, tac, cat
tic
Order of groups can be different but group members should be same.
The basic idea used is simple. Insert the individual words of the sequence in a trie but before inserting a word sort it according to the characters. This way, when anagrams are inserted into a trie, their path from root node to leaf node would be exactly the same and if we store the indices of the words in given sequence at leaf node, then we would be able to print all anagrams in grouped manner. The idea is illustrated in below trie diagram.
11 | final static int ALPHABET_SIZE = 26; |
12 | |
13 | class TrieNode |
14 | { |
15 | |
16 | ArrayList<Integer> anagramIndices; |
17 | TrieNode[] children; |
18 | |
19 | TrieNode() |
20 | { |
21 | children = new TrieNode[ALPHABET_SIZE]; |
22 | this.anagramIndices = new ArrayList(); |
23 | } |
24 | } |
25 | |
26 | TrieNode root; |
27 | |
28 | TrieForGroupingAnagrams() |
29 | { |
30 | this.root = new TrieNode(); |
31 | } |
32 | |
33 | private int getIndex(char ch) |
34 | { |
35 | return ch - 'a'; |
36 | } |
37 | |
38 | public void insertIntoTrie(String key, int index, HashMap anagramNodes) |
39 | { |
40 | |
41 | if (key == null) return; |
42 | |
43 | key = key.toLowerCase(); |
44 | |
45 | TrieNode currentNode = this.root; |
46 | int charIndex = 0; |
47 | |
48 | while (charIndex < key.length()) |
49 | { |
50 | int childIndex = getIndex(key.charAt(charIndex)); |
51 | |
52 | if (childIndex < 0 || childIndex >= ALPHABET_SIZE) |
53 | { |
54 | System.out.println("Invalid Key" ); |
55 | return; |
56 | } |
57 | |
58 | if (currentNode.children[childIndex] == null) |
59 | { |
60 | currentNode.children[childIndex] = new TrieNode(); |
61 | } |
62 | |
63 | currentNode = currentNode.children[childIndex]; |
64 | |
65 | charIndex += 1; |
66 | } |
67 | |
68 | if (charIndex == key.length()) |
69 | { |
70 | currentNode.anagramIndices.add(index); |
71 | anagramNodes.put(currentNode, currentNode.anagramIndices); |
72 | } |
73 | |
74 | return; |
75 | } |
76 | |
77 | public void printGroupedAnagrams(String[] sequence) |
78 | { |
79 | HashMap<TrieNode, ArrayList<Integer>> anagramNodes = new HashMap(); |
80 | for (int i = 0; i < sequence.length; i++) |
81 | { |
82 | char[] charSequence = sequence[i].toCharArray(); |
83 | Arrays.sort(charSequence); |
84 | |
85 | insertIntoTrie(new String(charSequence), i, anagramNodes); |
86 | } |
87 | |
88 | Iterator<ArrayList<Integer>> mapItr = anagramNodes.values().iterator(); |
89 | while (mapItr.hasNext()) |
90 | { |
91 | ArrayList<Integer> currentAnagramList = mapItr.next(); |
92 | for (int j = 0; j < currentAnagramList.size(); j++) |
93 | { |
94 | int indexIntoSequence = currentAnagramList.get(j); |
95 | System.out.print(" " + sequence[indexIntoSequence]); |
96 | } |
97 | System.out.println("" ); |
98 | } |
99 | } |