RThomP RThomP - 5 months ago 16
Java Question

Storing groups of words in hashtable

I have an ArrayList of words, and I want to compare the words against each other, to store them in a HashTable (in groups of anagrams).

I know how to compare two words to test if they are an anagram, but I can't figure out how to compare a longer list of words.

For example:


  • There 10 words in the list

  • 5 of them are anagrams of each other

  • 2 of them are also anagrams of each other (but not of the first group)

  • So, 3 groups; 1 group of one set of anagrams (5 words), 1 group for the other set (2 words), and 1 group (3 words) of random words



How do I compare the 10 words to find those 5+2 anagrams, and store those anagrams groups (separately) into a hashtable?

EDIT:

The code I have for comparing two words:

public static boolean isAnagram(String firstWord, String secondWord) {

boolean anagram;
if (firstWord.length() != secondWord.length()) {
return false;
}
firstWord = firstWord.toLowerCase();
secondWord=secondWord.toLowerCase();
char[] c1 = firstWord.toCharArray();
char[] c2 = secondWord.toCharArray();
Arrays.sort(c1);
Arrays.sort(c2);
String sc1 = new String(c1);
String sc2 = new String(c2);
if (sc1.equals(sc2)) {
System.out.println("ANAGRAMS");
} else {
System.out.println("NOT ANAGRAMS");
}
return sc1.equals(sc2);
}


I'm sure this could be adapted to work with comparing an unlimited amount of strings. Then the next dilemma is ensuring that the separate groups of anagrams are stored in the hashtable.

Answer Source
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class AnagramDetector {
    public static void main(String[] args) {
        List<String> words = new ArrayList<>();
        words.add("Abc");
        words.add("cba");
        words.add("bca");
        words.add("bc");
        words.add("ba");
        words.add("ab");

        MultiValueMap<String, String> res = new LinkedMultiValueMap<>();
        words.stream().forEach(word -> {
            String key = getAnagramKey(word);
            res.add(key, word);
        });
        System.out.println(res);
    }
    public static String getAnagramKey(String word) {
        char[] c = word.toLowerCase().toCharArray();
        Arrays.sort(c);
        return new String(c);
    }

}

UPDATE for Hashtable:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Hashtable;
import java.util.List;

public class AnagramDetector {
    public static void main(String[] args) {
        List<String> words = new ArrayList<>();
        words.add("Abc");
        words.add("cba");
        words.add("bca");
        words.add("bc");
        words.add("ba");
        words.add("ab");

        Hashtable<String, List<String>> res = new Hashtable<>();
        words.stream().forEach(word -> {
            String key = getAnagramKey(word);
            List<String> anWords = res.get(key);
            if (anWords == null) {
                anWords = new ArrayList<>();
                res.put(key, anWords);
            }
            anWords.add(word);
        });
        System.out.println(res);
    }
    public static String getAnagramKey(String word) {
        char[] c = word.toLowerCase().toCharArray();
        Arrays.sort(c);
        return new String(c);
    }

}