Trie + recursion + pruning to implement Boggle

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 dictionary
		Trie 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 dictionary
		if (!trie.isPrefixExisted(word)) {
			list.remove(list.size() - 1);
			isVisited[i][j] = false;
			return;
		}
		//satisfy the condition
		if (word.length() >= 3 && trie.isWordExisted(word)) {
			allWordsList.add(word);
		}
		//different directions
		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);
		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 string
	public 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.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值