Trie + recursion + pruning to implement Boggle

来源:互联网 发布:报警电话 知乎 编辑:程序博客网 时间:2024/05/17 05:17

If you want to know what Boggle is, please wiki or google it. Or refer to http://goo.gl/GythQ 

In this implementation, we need to use a dictionary. Go to http://goo.gl/vaq4Z to download it and as it as input.in.

Trie Class

public class Trie {private Node root;     public Trie(){        root = new Node(' ');     }     public void insert(String word){    if(isWordExisted(word) == true) return;        Node current = root;         for(int i = 0; i < word.length(); i++){            Node child = current.subNode(word.charAt(i));            if(child != null){                 current = child;            } else {                 current.childList.add(new Node(word.charAt(i)));                 current = current.subNode(word.charAt(i));            }            current.count++;        }         // Set isEnd to indicate end of the word        current.isEnd = true;    }    public boolean isWordExisted(String word){    Node current = root;            for(int i = 0; i < word.length(); i++){                if(current.subNode(word.charAt(i)) == null)                return false;            else                current = current.subNode(word.charAt(i));        }        if (current.isEnd == true) return true;        else return false;    }        public boolean isPrefixExisted(String word){    Node current = root;    for(int i = 0; i < word.length(); i++){                if(current.subNode(word.charAt(i)) == null)                return false;            else                current = current.subNode(word.charAt(i));        }        return true;    }}class Node {    char content; // the character in the node    boolean isEnd; // whether the end of the words    int count;  // the number of words sharing this character    LinkedList<Node> childList; // the child list      public Node(char c){        childList = new LinkedList<Node>();        isEnd = false;        content = c;        count = 0;    }      public Node subNode(char c){        if(childList != null){        for(Node eachChild : childList){            if(eachChild.content == c){                 return eachChild;            }        }        }        return null;   }}

Boggle Class

public class Boggle {public static void main(String[] args) {char[][] board = {{'d', 'g', 'h', 'i'}, {'k', 'l', 'p', 's'}, {'y', 'e', 'u', 't'}, {'e', 'o', 'r', 'n'}};String path = "input.in";ArrayList<String> allWordsList = findAllValidWords(board, path);for (String str : allWordsList) {System.out.println(str);}}// find all the valid words in the board, and the dictionary can be found in "path"public static ArrayList<String> findAllValidWords(char[][] board, String path) {ArrayList<String> allWordsList = new ArrayList<String>();if (board == null || board.length == 0 || board[0].length == 0) return allWordsList;// trie stores the dictionaryTrie trie = generateTrie(path);for (int i = 0; i < board.length; i++) {for (int j = 0; j < board[0].length; j++) {boolean[][] isVisited = new boolean[board.length][board[0].length];helper(board, i, j, new ArrayList<Character>(), isVisited, trie, allWordsList);}}return allWordsList;}public static void helper(char[][] arr, int i, int j, ArrayList<Character> list, boolean[][] isVisited, Trie trie, ArrayList<String> allWordsList) {if (i < 0 || j < 0 || i >= arr.length || j >= arr[0].length || isVisited[i][j]) return;list.add(arr[i][j]);isVisited[i][j] = true;String word = convertToString(list);// the prefix doesn't exist in the dictionaryif (!trie.isPrefixExisted(word)) {list.remove(list.size() - 1);isVisited[i][j] = false;return;}//satisfy the conditionif (word.length() >= 3 && trie.isWordExisted(word)) {allWordsList.add(word);}//different directionshelper(arr, i - 1, j, list, isVisited, trie, allWordsList);helper(arr, i - 1, j - 1, list, isVisited, trie, allWordsList);helper(arr, i - 1, j + 1, list, isVisited, trie, allWordsList);helper(arr, i, j - 1, list, isVisited, trie, allWordsList);helper(arr, i, j + 1, list, isVisited, trie, allWordsList);helper(arr, i + 1, j, list, isVisited, trie, allWordsList);helper(arr, i + 1, j - 1, list, isVisited, trie, allWordsList);helper(arr, i + 1, j + 1, list, isVisited, trie, allWordsList);list.remove(list.size() - 1);isVisited[i][j] = false;}// convert arraylist to stringpublic static String convertToString(ArrayList<Character> list) {StringBuilder sb = new StringBuilder();for (Character c : list) {sb.append(c);}return sb.toString();}// create trie based on the dictionary public static Trie generateTrie(String path) {Trie trie = new Trie();try {BufferedReader br = new BufferedReader(new FileReader(path));String strWord = "";while ((strWord = br.readLine()) != null) {trie.insert(strWord);}br.close();} catch (IllegalArgumentException e) {System.out.println(e.getMessage());return null;} catch (IOException e) {System.out.println(e.getMessage());return null;}return trie;}}

Reference: http://www.technicalypto.com/2010/04/trie-in-java.html

Please add a reference to http://blog.csdn.net/beiyetengqing when using the code. Thanks.

原创粉丝点击