package cse1030.games.wordgames; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; /** * A utility class containing methods related to word games. * * @author CSE1030_W14 * */ public class WordGamesUtil { /** * A dictionary of lower case English words. The dictionary cannot be * modified. */ public static final Dictionary DICTIONARY = Dictionary.INSTANCE; /** * Private constructor to prevent instantiation. */ private WordGamesUtil() { throw new UnsupportedOperationException(); } /** * Determines if two strings are adjacent words. The string s is * adjacent to t if and only if all of the following conditions * are true: * * * * @param s * a string * @param t * a string * @return true if s and t are * adjacent, and false otherwise */ public static boolean areAdjacent(String s, String t) { // is s in the dictionary? if (!WordGamesUtil.DICTIONARY.contains(s)) { return false; } // is t in the dictionary? if (!WordGamesUtil.DICTIONARY.contains(t)) { return false; } // do s and t have the same length? if (s.length() != t.length()) { return false; } // count the number of letters n that are different in s and t int n = 0; for (int i = 0; i < s.length(); i++) { if (s.charAt(i) != t.charAt(i)) { n++; } } return n == 1; } /** * Returns a sorted set of all words in * WordGamesUtility.DICTIONARY that are adjacent to the string * s. The sorting of the elements of the set is lexicographical * (dictionary order). * * @param s * a string * @return a sorted set of words in WordGamesUtility.DICTIONARY * that are adjacent to s */ public static SortedSet allAdjacentTo(String s) { SortedSet result = new TreeSet(); for (String word : DICTIONARY) { if (areAdjacent(word, s)) { result.add(word); } } return result; } /** * Determines if the string s is an isogram. This method returns * true if and only if all of the following conditions are * true: * *
    *
  • the string s is in * WordGamesUtility.DICTIONARY
  • *
  • all of the letters in s occur only once
  • *
* * @param s * a string * @return true if a is an isogram of s * , and false otherwise */ public static boolean isIsogram(String s) { // is s in the dictionary? if (!WordGamesUtil.DICTIONARY.contains(s)) { return false; } Set letters = new TreeSet(WordGamesUtil.toList(s)); return letters.size() == s.length(); } /** * Returns a sorted set of all isograms in * WordGamesUtility.DICTIONARY. The sorting of the elements of * the set is lexicographical (dictionary order). * * @return a sorted set of isograms in * WordGamesUtility.DICTIONARY */ public static SortedSet allIsograms() { SortedSet result = new TreeSet(); for (String word : DICTIONARY) { if (isIsogram(word)) { result.add(word); } } return result; } /** * Returns a new list containing each character in the string s * in the same order that they appear in s * * @param s * a string * @return a new list containing each character in the string s * in the same order that they appear in s */ public static List toList(String s) { List t = new ArrayList(); for (int i = 0; i < s.length(); i++) { t.add(s.charAt(i)); } return t; } /** * Returns a new string formed by concatenating all of the characters stored * in the given list in sequential order (from the first element to the last * element). * * @param t * a list of characters * @return a string formed by concatenating the characters stored in * t in sequential order */ public static String fromList(List t) { StringBuilder b = new StringBuilder(); for (Character c : t) { b.append(c); } return b.toString(); } /** * Determines if a string is an anagram of a second string. This method * returns true if and only if all of the following conditions * are true: * *
    *
  • the string a is in * WordGamesUtility.DICTIONARY
  • *
  • the string s is in * WordGamesUtility.DICTIONARY
  • *
  • the string a is the same length as s
  • *
  • all of the letters in a occur with the same frequency as * the letters in s
  • *
* * @param a * a string * @param s * another string * @return true if a is an anagram of s * , and false otherwise */ public static boolean isAnagramOf(String a, String s) { if (!WordGamesUtil.DICTIONARY.contains(a)) { return false; } if (!WordGamesUtil.DICTIONARY.contains(s)) { return false; } List aAsList = WordGamesUtil.toList(a); List sAsList = WordGamesUtil.toList(s); Collections.sort(aAsList); Collections.sort(sAsList); return aAsList.equals(sAsList); } /** * Returns a new string containing all of the letters of the given string in a * new random order. The scrambled string has the same length as * s, and is created by randomly shuffling the order of the * letters in s. All possible permutations of the letters of * s are expected to occur with approximately equal likelihood. * * @param s * a string * @return an new string having the same length as s, and * containing all of the letters of s in a new random * order */ public static String scramble(String s) { List sAsList = toList(s); Collections.shuffle(sAsList); return fromList(sAsList); } }