/** * This class shows two simple examples of maps. Both examples * map a canonical form of a word to a list of words sharing that * canonical form. For anagrams, the canonical form is a sorted version * of the word, e.g., "abegl" for both "bagel" and "gable". The other * example is based on texting with cell phones, but without * using multiple key presses for the letter 'C', which typically requires * three presses of the 2 key. In this example, the canonical * form of "CAB" is 222 since all letters are on the 2-key. The words * "adopts" and "census" both share a key-pad canonical form of * "125676". * * @author ola * */ import java.io.File; import java.util.*; import javax.swing.JFileChooser; public class TextingWords { private static class SortedWord implements ICanonicalizer{ /** * Returns a sorted form of a string, i.e., a string formed * by sorting the letters. */ public String canonical(String word){ char[] list = word.toCharArray(); Arrays.sort(list); return new String(list); } } private static class KeyPadWord implements ICanonicalizer{ /** * Create the map of letters to the cell-phone key * on which the letter occurs. */ private static Map myKeyMap = new HashMap(); static{ String[] keys = { ".-'","abc", "def", "ghi", "jkl", "mno","pqrs","tuv","wxyz" }; for(int k = 0; k < keys.length; k++){ Integer value = new Integer(k); for(int j=0; j < keys[k].length(); j++){ myKeyMap.put(keys[k].substring(j,j+1), value); } } } /** * Returns keypad form of word, e.g., for "ant" returns "268", * and for "cab" returns "222". */ public String canonical(String word){ String ret = ""; for(int k=0; k < word.length(); k++){ ret += myKeyMap.get(word.substring(k,k+1).toLowerCase()); } return ret; } } private ArrayList myWords; // words read to be dictionary private static JFileChooser ourChooser = new JFileChooser("."); /** * Construct an object with words from client-chosen * file (client can cancel reading when prompted). Stores * words for subsequent use. */ public TextingWords(){ myWords = new ArrayList(); readDictionary(); } /** * Prompt user and store words from file chosen * (if operation not cancelled). */ public void readDictionary(){ int retval = ourChooser.showOpenDialog(null); if (retval == JFileChooser.APPROVE_OPTION){ File f = ourChooser.getSelectedFile(); Scanner s = new Scanner(f); while (s.hasNext()){ String word = (String) s.next(); myWords.add(word); } System.out.println("read "+myWords.size()+" words"); } } public String getCanonical(String word, Map m){ Iterator it = m.keySet().iterator(); while (it.hasNext()){ String key = (String) it.next(); List list = (List) m.get(key); if (list.contains(word)){ return key; } } throw new NoSuchElementException(word+" not found"); } /** * Run all words through a canonicalizer and return a map of canonical form * to list of words sharing the canonical form. The keys in the returned * map are strings and the associated value for a key is the list of strings sharing * the canonical form that is the key. * @param changer is the canonicalizer used to transform all words in the dictionary * @return a map of canonical form (key) to list sharing key */ public Map processWords(ICanonicalizer changer){ Map m = new TreeMap(); Iterator it = myWords.iterator(); int count = 0; while (it.hasNext()){ String s = (String) it.next(); String key = changer.canonical(s); List list = (List) m.get(key); if (list == null){ list = new ArrayList(); list.add(s); m.put(key, list); } else { list.add(s); } count++; if (count % 1000 == 0){ System.out.println("processed "+count+" words"); } } return m; } /** * Print canonical form and associated list if the list's size * is greater than a provided threshold * @param map is the map storing canonical forms/lists * @param minSize is the threshold for lists printed */ public void printMany(Map map, int minSize){ Iterator it = map.keySet().iterator(); while (it.hasNext()){ String text = (String) it.next(); List list = (List) map.get(text); if (list.size() > minSize){ System.out.print(text+"\t"); Iterator lit = list.iterator(); while (lit.hasNext()){ System.out.print(" "+lit.next()); } System.out.println(); } } } public static void main(String[] args){ TextingWords tw = new TextingWords(); ICanonicalizer ana = new SortedWord(); ICanonicalizer text = new KeyPadWord(); Map map = tw.processWords(text); tw.printMany(map,6); System.exit(0); } }