SBS(3)-- HashMap递归实现单词重组(AnagramSolver)Java

HashMap介绍链接:
Java 集合系列10之 HashMap详细介绍(源码解析)和使用示例

输入输出:
Welcome to the cse143 anagram solver.
What is the name of the dictionary file? dict3.txt
phrase to scramble (return to quit)? Howard Dean
Max words to include (0 for no max)? 2
[ahead, drown]
[don, warhead]
[drown, ahead]
[hadron, wade]
[head, onward]
[nod, warhead]
[onward, head]
[wade, hadron]
[warhead, don]
[warhead, nod]
phrase to scramble (return to quit)? Donald TRUMP
Max words to include (0 for no max)? 2
[doldrum, pant]
[mud, portland]
[pant, doldrum]
[portland, mud]
phrase to scramble (return to quit)?

package ass6;
// AnagramMain contains a main 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 AnagramSolver object to do the actual
// search for anagrams that match the user's phrases.

import java.io.*;
import java.util.*;

public class AnagramMain {
    public static void main(String[] args) throws FileNotFoundException {
        System.out.println("Welcome to the cse143 anagram solver.");
        System.out.println();

        // open the dictionary file
        Scanner console = new Scanner(System.in);
        System.out.print("What is the name of the dictionary file? ");
        Scanner input = new Scanner(new File("E:\\Workspace\\IDEA\\Algorithm\\src\\main\\java\\ass6\\" + console.nextLine()));

        // read dictionary into an ArrayList
        List<String> dictionary = new ArrayList<String>();
        while (input.hasNextLine()) {
            dictionary.add(input.nextLine());
        }

        // solve anagrams
        List<String> dictionary2 = Collections.unmodifiableList(dictionary);
        AnagramSolver solver = new AnagramSolver(dictionary2);
        boolean done = false;
        while (!done) {
            System.out.println();
            System.out.print("phrase to scramble (return to quit)? ");
            String phrase = console.nextLine();
            if (phrase.length() == 0) {
                done = true;
            } else {
                System.out.print("Max words to include (0 for no max)? ");
                int max = console.nextInt();
                console.nextLine();  // to skip newline after int
                solver.print(phrase, max);
            }
        }
    }
}
package ass6;

import java.util.*;

public class AnagramSolver {

    private Map<String, LetterInventory> dictionary;                //dictionary map
    private Map<String, LetterInventory> anaMap;                    //construct a small map to find more efficient

    public AnagramSolver(List<String> list) {                       //constructor
        dictionary = new HashMap<String, LetterInventory>();        //construct dictionary
        for (int i = 0; i < list.size(); i++) {
            String keyStr = list.get(i);
            LetterInventory valLi = new LetterInventory(keyStr);
            dictionary.put(keyStr, valLi);                          //key : key string    value : LetterInventory
        }
    }

    public void print(String phrase, int max) {
        if (max < 0 || phrase == null) {
            throw new IllegalArgumentException();
        }

        LetterInventory input = new LetterInventory(phrase);        //user input
        anaMap = new HashMap<String, LetterInventory>();            //store anagram by map
        List<List<String>> result = new ArrayList<List<String>>();

        for (String keyStr : dictionary.keySet()) {                 //traverse dictionary
            if (input.subtract(dictionary.get(keyStr)) != null)     //store key value with anagram map if find subString of input
                anaMap.put(keyStr, dictionary.get(keyStr));
        }
//        for (int i = 0; i < dictionary.keySet().size(); i++) {                                     //???
//            if (input.subtract(dictionary.get(dictionary.keySet().iterator().next())) != null) {   //???
//                anaMap.add(dictionary.get(dictionary.keySet().iterator().next()));                 //???
//            }
//        }
        ArrayList<String> anaList = new ArrayList<String>();
        printResult(input, anaList, max, anaMap, 0);          //recursive method
    }

    private void printResult(LetterInventory input,
                             ArrayList<String> anaList, int max,
                             Map<String, LetterInventory> anaDict, int size) {

        LetterInventory iterLi;                                     //iterator key in anagram map
        LetterInventory leftLi;                                     //left LetterInventory after subtract
        if (size < max || max == 0) {
            Iterator<String> it = anaDict.keySet().iterator();
            if (!it.hasNext() && size == 0) {                       //output [] if 1234
                System.out.println(anaList.toString());
            }
            while (it.hasNext()) {
                String key = it.next();
                iterLi = new LetterInventory(key);
                leftLi = input;
                if (leftLi.subtract(iterLi) != null) {
                    anaList.add(key);                               //add key into anagram list if input contains iterator key
                    leftLi = input.subtract(iterLi);
                    if (leftLi.isEmpty()) {
                        System.out.println(anaList.toString());     //print if match
                    } else {
                        printResult(leftLi, anaList, max, anaDict, size + 1);   //recursive if there is sth left
                    }
                    anaList.remove(anaList.size() - 1);       //backtracking
                }
            }

        }
    }
}
package ass6;

//A class that stores and process a String of letters
//including sort in alphabetic order, addition, subtraction
//and number of letter edition methods
public class LetterInventory {

    //store the letter String that user initialized
    private String alphabetic = "";

    //ignore case of letters and non-alphabetic characters
    //store the input into global variable
    LetterInventory(String data) {
        String ignoreCase = data.toLowerCase();
        for (int i = 0; i < ignoreCase.length(); i++) {
            if (Character.isLetter(ignoreCase.charAt(i))) {
                alphabetic += ignoreCase.charAt(i);
            }
        }
    }

    //Pre:input letter should be valid alphabetic letter
    //(throws an IllegalArgumentException otherwise)
    //
    //Post:returns a count of how many of this letter are in the inventory
    public int get(char letter) {
        int count = 0;
        if (!Character.isLetter(letter)) {
            throw new IllegalArgumentException("input should be valid letter");
        }
        for (int i = 0; i < alphabetic.length(); i++) {
            if (alphabetic.charAt(i) == Character.toLowerCase(letter)) {
                count++;
            }
        }
        return count;

    }

    //Pre:input letter should be valid alphabetic letter
    //(throws an IllegalArgumentException otherwise)
    //input value should be non-negative (throws an IllegalArgumentException otherwise)
    //
    //Post:sets the count for the given letter to the given value
    public void set(char letter, int value) {
        if (value < 0) {
            throw new IllegalArgumentException("the input number should be non-negative");
        }
        if (!Character.isLetter(letter)) {
            throw new IllegalArgumentException("input should be valid letter");
        }
        char lowerLetter = Character.toLowerCase(letter);
        String withoutLetter = "";
        for (int i = 0; i < alphabetic.length(); i++) {
            if (alphabetic.charAt(i) != lowerLetter) {
                withoutLetter += alphabetic.charAt(i);
            }
        }
        alphabetic = withoutLetter;
        for (int i = 0; i < value; i++) {
            alphabetic += lowerLetter;
        }
    }

    //returns the sum of all of the counts in this inventory
    public int size() {
        return alphabetic.length();
    }

    //return true if the inventory is empty
    public boolean isEmpty() {
        return alphabetic.equals("");
    }

    //Returns a String representation of the inventory
    //with the letters all in lowerCase and in sorted order
    //and surrounded by square brackets
    public String toString() {
        String sorted = "";
        for (char character = 97; character < 123; character++) {
            for (int i = 0; i < alphabetic.length(); i++) {
                if (alphabetic.charAt(i) == character)
                    sorted += character;
            }
        }
        return "[" + sorted + "]";
    }

    //Takes a LetterInventory object
    //Constructs and returns a new LetterInventory object
    //that represents the sum of this letter inventory
    //and the other given LetterInventory
    public LetterInventory add(LetterInventory other) {
        String addition = alphabetic + other.toString();
        LetterInventory LIadd = new LetterInventory(addition);
        return LIadd;
    }

    //Takes a LetterInventory object
    //Constructs and returns a new LetterInventory object
    //that represents the result of subtracting
    //the other inventory from this inventory
    //return null if resulting count is negative
    public LetterInventory subtract(LetterInventory other) {
        String subtrResult = alphabetic;
        String subtr = other.toString().substring(1, other.toString().length() - 1);
        int indexNum;
        for (int i = 0; i < subtr.length(); i++) {
            indexNum = subtrResult.indexOf(subtr.charAt(i));
            if (indexNum < 0) {
                return null;
            } else {
                subtrResult = subtrResult.substring(0, indexNum)
                        + subtrResult.substring(indexNum + 1);
            }

        }
        LetterInventory LIsubtr = new LetterInventory(subtrResult);
        return LIsubtr;
    }

}

dict1.txt:

abash
aura
bar
barb
bee
beg
blush
bog
bogus
bough
bow
brew
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
owe
rub
sew
she
shrub
shrug
sub
surge
swore
web
wee
were
whore
whose
woe
wore
worse

猜你喜欢

转载自blog.csdn.net/Dooonald/article/details/80369928