diff --git a/anagrams/AnagramMain.java b/anagrams/AnagramMain.java new file mode 100644 index 0000000..70a9675 --- /dev/null +++ b/anagrams/AnagramMain.java @@ -0,0 +1,97 @@ +/** +CSE 143, Winter 2010, Marty Stepp +Homework 6 (Anagrams) + +AnagramMain is a client program that prompts a user for the name of a +dictionary file and then gives the user the opportunity to find anagrams of +various phrases. It constructs an Anagrams object to do the actual +search for anagrams that match the user's phrases. + +@author Stuart Reges and Marty Stepp +@version originally written by reges on 5/9/2005; modified by stepp on 2/6/2010 +*/ + +import java.io.File; +import java.io.FileNotFoundException; +import java.util.Collections; +import java.util.Scanner; +import java.util.Set; +import java.util.TreeSet; + +public class AnagramMain { + // dictionary file to use for input (change to dict2, dict3) + private static final String DICTIONARY_FILE = "dict1.txt"; + + // set to true to test runtime and # of letter inventories created + private static final boolean TIMING = true; + private static final boolean DEBUG = false; + + + public static void main(String[] args) throws FileNotFoundException { + System.out.println("Welcome to the CS 145 anagram solver."); + System.out.println("Using dictionary file " + DICTIONARY_FILE + "."); + + // read dictionary into a set + Scanner input = new Scanner(new File(DICTIONARY_FILE)); + Set dictionary = new TreeSet(); + while (input.hasNextLine()) { + dictionary.add(input.nextLine()); + } + dictionary = Collections.unmodifiableSet(dictionary); // read-only + + // create Anagrams object for, well, solving anagrams + Anagrams solver = new Anagrams(dictionary); + + // get first phrase to solve + Scanner console = new Scanner(System.in); + String phrase = getPhrase(console); + + if (DEBUG) { + phrase = "barbara bush"; + } + // loop to get/solve each phrase + while (phrase.length() > 0) { + System.out.println("All words found in \"" + phrase + "\":"); + Set allWords = solver.getWords(phrase); + System.out.println(allWords); + System.out.println(); + + System.out.print("Max words to include (Enter for no max)? "); + String line = console.nextLine().trim(); + if (DEBUG) { + line = "4"; + } + + long startTime = System.currentTimeMillis(); + if (line.length() > 0) { + // use a max + int max = new Scanner(line).nextInt(); + solver.print(phrase, max); // print all anagrams of phrase + } else { + // no max + solver.print(phrase); // print all anagrams of phrase + } + long endTime = System.currentTimeMillis(); + System.out.println(); + + // 12247 ms elapsed, 2594392 unique LetterInventory object(s) created + if (TIMING) { + long elapsed = endTime - startTime; + int inventories = LetterInventory.getInstanceCount(); + System.out.println(elapsed + " ms elapsed, " + inventories + + " unique LetterInventory object(s) created"); + LetterInventory.resetInstanceCount(); + } + + // get next phrase to solve + phrase = getPhrase(console); + } + } + + // Helper to prompt for a phrase to generate anagrams. + public static String getPhrase(Scanner console) { + System.out.println(); + System.out.print("Phrase to scramble (Enter to quit)? "); + return console.nextLine().trim(); + } +} diff --git a/anagrams/Anagrams.java b/anagrams/Anagrams.java new file mode 100644 index 0000000..235099c --- /dev/null +++ b/anagrams/Anagrams.java @@ -0,0 +1,148 @@ +/** +* +* Matt Jensen +* 5/28/19 +* CS 145 +* Assignment 3 - Anagrams +* +* Finds and prints all anagrams for a specific phrase. +* Uses recursive backtracking. +* +*/ + +import java.util.*; + +public class Anagrams { + + private Set dictionary; + private int max; + private String phrase; + private List solution = new ArrayList(); + private Set foundSolutions = new HashSet(); + private Map inventories = new HashMap(); + + public Anagrams(Set dictionary){ + this.setDictionary(dictionary); + } + + // @returns words anagrams in dictionary made with the word + public Set getWords(String phrase){ + Set anagrams = new TreeSet(); + if( ! this.inventories.keySet().contains(phrase) ) { + this.inventories.put(phrase, new LetterInventory(phrase)); + } + LetterInventory inventory = this.getInventory(phrase); + for(String dictionaryWord : this.dictionary) { + if(inventory.contains(dictionaryWord)){ + anagrams.add(dictionaryWord); + } + } + return anagrams; + } + // easier signature without max. + public void print(String phrase){ + print(phrase, this.getWords(phrase).size()); + } + // populates foundSolutions then prints each to console. + public void print(String phrase, int max){ + this.setPhrase(phrase); + this.setMax(max); + this.findSolutions(); + for(String[] solution : this.getSolutions() ) { + System.out.println(Arrays.toString(solution)); + } + } + + // private methods. + // called to populate foundSolutions. + private void findSolutions() { + this.foundSolutions = new HashSet(); + this.solution = new ArrayList(); + LetterInventory inventory = this.getInventory(this.getPhrase()); + this.findSolutions(inventory); + } + + private void findSolutions(LetterInventory remainingInventory) { + // check if solution + if(remainingInventory.isEmpty()) { + this.addSolution(); + return; + } + // guesses. + Set values = this.getWords(phrase); + for( String value : values ) { + if( isValid(value, remainingInventory) ) { + applyValue(value, remainingInventory); + findSolutions(remainingInventory); + removeValue(value, remainingInventory); + } + + } + return; + } + + // tests is the value makes the decision tree dead end. + private boolean isValid(String value, LetterInventory inventory) { + if( ! inventory.contains(value)) { + return false; + } + return true; + } + // backtracks the apply value step. + private void removeValue(String value, LetterInventory inventory) { + inventory.add(value); + this.solution.remove(value); + } + // adds the value to solution currently being built. + private void applyValue(String value, LetterInventory inventory) { + inventory.subtract(value); + this.solution.add(value); + } + + // methods for saving a found solution + private void addSolution() { + if( this.solution.size() > this.max) { + return; + } + int i = 0; + String[] newSolution = new String[this.solution.size()]; + for(String word : this.solution) { + newSolution[i] = word; + i++; + } + this.foundSolutions.add(newSolution); + } + + // setters and getters for class variables. + private Set getSolutions() { + return this.foundSolutions; + } + private List getSolution() { + return this.solution; + } + private LetterInventory getInventory(String phrase) { + return this.inventories.get(phrase); + } + private void setDictionary(Set dictionary) { + this.dictionary = dictionary; + } + // sets the max or as the total number of found words in the phrase. + private void setMax(int max) { + if( max > 0 ) { + this.max = max; + } + else{ + this.max = this.getWords(this.getPhrase()).size(); + } + } + // errors if phrase is null or sets class phrase variable. + private void setPhrase(String phrase) { + if(phrase == null) { + throw new IllegalArgumentException(); + } + this.phrase = phrase; + } + private String getPhrase() { + return this.phrase; + } +} diff --git a/anagrams/Helper.java b/anagrams/Helper.java new file mode 100644 index 0000000..4c1c64d --- /dev/null +++ b/anagrams/Helper.java @@ -0,0 +1,53 @@ + +import java.util.*; + +public class Helper { + + public static boolean isSolution(int max, LetterInventory inventory, Set foundWords) { + if( inventory.isEmpty() ) { + return true; + } + if( foundWords.size() >= max) { + return true; + } + return false; + } + + public static void displaySolution(Set foundWords) { + System.out.println(Arrays.toString(foundWords.toArray())); + return; + } + + public static boolean isValid(int max, LetterInventory inventory, Set foundWords, Set remainingWords ) { + String next = ""; + for( String found : foundWords ) { + next = found; + } + if(inventory.contains(next)) { + if( foundWords.size() <= max - 1 ) { + return true; + } + } + return false; + } + public static void applyValue(int max, LetterInventory inventory, Set foundWords, Set remainingWords ) { + String next = ""; + for( String found : foundWords ) { + next = found; + } + inventory.subtract(next); + foundWords.add(next); + remainingWords.remove(next); + return; + } + public static void removeValue(int max, LetterInventory inventory, Set foundWords, Set remainingWords ) { + String next = ""; + for( String found : foundWords ) { + next = found; + } + inventory.add(next); + foundWords.remove(next); + remainingWords.add(next); + return; + } +} diff --git a/anagrams/README.md b/anagrams/README.md new file mode 100644 index 0000000..0d46ad9 --- /dev/null +++ b/anagrams/README.md @@ -0,0 +1,6 @@ +# Anagrams + +This program focuses on recursive backtracking. + +# Description +A class called Anagrams that uses a dictionary to find all anagram phrases that match a given word or phrase. You are provided with a client program AnagramMain that prompts the user for phrases and then passes those phrases to your Anagrams object. It asks your object to print all anagrams for those phrases. diff --git a/anagrams/Recursion.java b/anagrams/Recursion.java new file mode 100644 index 0000000..3977d30 --- /dev/null +++ b/anagrams/Recursion.java @@ -0,0 +1,41 @@ +import java.util.*; + +public interface Recursion { + public static void main(String[] args) { + + } + private boolean findSolutions(int n) { + // check if solution + boolean foundSolution = false; + if(foundSolution) { + displaySolution(); + return true; + } + // guesses. + List values = new ArrayList(); + for( String value : values ) { + if( isValid(value, n) ) { + applyValue(value, n); + if( findSolutions(n - 1) ) { + return true; + } + removeValue(value, n); + } + + } + return false; + } + + private boolean isValid(String value, int n) { + return true; + } + private void removeValue(String value, int n) { + + } + private void applyValue(String value, int n) { + + } + private void displaySolution() { + System.out.println(); + } +} diff --git a/anagrams/dict1.txt b/anagrams/dict1.txt new file mode 100644 index 0000000..5637020 --- /dev/null +++ b/anagrams/dict1.txt @@ -0,0 +1,60 @@ +abash +aura +bar +barb +bee +beg +blush +bog +bogus +bough +bow +brew +briar +brow +brush +bug +bugs +bus +but +egg +ego +erg +ghost +go +goes +gorge +gosh +grew +grow +grub +gush +he +her +here +hew +hog +hose +how +hub +hug +huh +hush +owe +rub +sew +she +shrub +shrug +sir +sub +surge +swore +web +wee +were +whore +whose +woe +wore +worse \ No newline at end of file diff --git a/anagrams/spec.pdf b/anagrams/spec.pdf new file mode 100644 index 0000000..c4579fd Binary files /dev/null and b/anagrams/spec.pdf differ