add anagram assignment from WCC CS 145 Spring 2019.

This commit is contained in:
Matthew Jensen 2019-12-13 15:33:17 -08:00
parent c988b7ce5c
commit d738aedc12
7 changed files with 405 additions and 0 deletions

97
anagrams/AnagramMain.java Normal file
View File

@ -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<String> dictionary = new TreeSet<String>();
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<String> 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();
}
}

148
anagrams/Anagrams.java Normal file
View File

@ -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<String> dictionary;
private int max;
private String phrase;
private List<String> solution = new ArrayList<String>();
private Set<String[]> foundSolutions = new HashSet<String[]>();
private Map<String, LetterInventory> inventories = new HashMap<String, LetterInventory>();
public Anagrams(Set<String> dictionary){
this.setDictionary(dictionary);
}
// @returns words anagrams in dictionary made with the word
public Set<String> getWords(String phrase){
Set<String> anagrams = new TreeSet<String>();
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<String[]>();
this.solution = new ArrayList<String>();
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<String> 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<String[]> getSolutions() {
return this.foundSolutions;
}
private List<String> getSolution() {
return this.solution;
}
private LetterInventory getInventory(String phrase) {
return this.inventories.get(phrase);
}
private void setDictionary(Set<String> 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;
}
}

53
anagrams/Helper.java Normal file
View File

@ -0,0 +1,53 @@
import java.util.*;
public class Helper {
public static boolean isSolution(int max, LetterInventory inventory, Set<String> foundWords) {
if( inventory.isEmpty() ) {
return true;
}
if( foundWords.size() >= max) {
return true;
}
return false;
}
public static void displaySolution(Set<String> foundWords) {
System.out.println(Arrays.toString(foundWords.toArray()));
return;
}
public static boolean isValid(int max, LetterInventory inventory, Set<String> foundWords, Set<String> 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<String> foundWords, Set<String> 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<String> foundWords, Set<String> remainingWords ) {
String next = "";
for( String found : foundWords ) {
next = found;
}
inventory.add(next);
foundWords.remove(next);
remainingWords.add(next);
return;
}
}

6
anagrams/README.md Normal file
View File

@ -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.

41
anagrams/Recursion.java Normal file
View File

@ -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<String> values = new ArrayList<String>();
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();
}
}

60
anagrams/dict1.txt Normal file
View File

@ -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

BIN
anagrams/spec.pdf Normal file

Binary file not shown.