Java Trie字典树,前缀树

Trie查询每个条目的时间复杂度,和字典中一共有多少条无关。

时间复杂度为O(W)

w为查询单词的长度

import java.util.TreeMap;

public class Trie {
	private class Node {
		public boolean isWord;
		public TreeMap<Character, Node> next;

		public Node(boolean isWord) {
			this.isWord = isWord;
			next = new TreeMap<>();
		}

		public Node() {
			this(false);
		}
	}

	private Node root;
	private int size;

	public Trie() {
		root = new Node();
		size = 0;
	}

	// 返回Trie中存储的单词数量
	public int getSize() {
		return size;
	}

	// 向Trie中添加一个新的单词word
	public void add(String word) {
		Node cur = root;
		for (int i = 0; i < word.length(); i++) {
			char c = word.charAt(i);
			if (cur.next.get(c) == null)
				cur.next.put(c, new Node());
			cur = cur.next.get(c);
		}
		if (!cur.isWord) {
			cur.isWord = true;
			size++;
		}
	}
    
	//查询单词word是否在Trie中
	public boolean contains(String word){
		Node cur=root;
		for (int i = 0; i < word.length(); i++) {
			char c=word.charAt(i);
			if(cur.next.get(c)==null)
				return false;
			cur=cur.next.get(c);
		}
		return cur.isWord;
	}
//查询是否在Trie中有单词以prefix为前缀
	public boolean isPrefix(String prefix) {
		Node cur=root;
		for (int i = 0; i < prefix.length(); i++) {
			char c=prefix.charAt(i);
			if(cur.next.get(c)==null)
				return false;
			cur=cur.next.get(c);
		}
		return true;
	}
}

测试:

public class Main {
	public static void Main(String[] args){
		 System.out.println("Pride and Prejudice");
         ArrayList<String> words=new ArrayList<>();
         if(FileOperation.readFile("pride-and-prejudice.txt", words)){

             long startTime = System.nanoTime();
             BSTSet<String> set=new BSTSet<String>();
             for(String word:words)
            	 set.add(word);
             for(String word:words)
            	 set.contains(word);

             long endTime = System.nanoTime();
             double time = (endTime - startTime) / 1000000000.0;

             System.out.println("Total different words: " + set.getSize());
             System.out.println("BSTSet: " + time + " s");
             
             startTime = System.nanoTime();

             Trie trie = new Trie();
             for(String word: words)
                 trie.add(word);

             for(String word: words)
                 trie.contains(word);

             endTime = System.nanoTime();

             time = (endTime - startTime) / 1000000000.0;

             System.out.println("Total different words: " + trie.getSize());
             System.out.println("Trie: " + time + " s");
         }
	}
}

  search可以搜索文字或正则表达式字符串,字符串只包含字母.或者a-z.

import java.util.TreeMap;

public class WordDictionary {
	public class Node{
	private boolean isWord;
	public TreeMap<Character, Node> next;
	public Node(boolean isWord){
		this.isWord=isWord;
		next=new TreeMap<>();
	}
		public Node() {
			this(false);
		}
	}
	 private  Node root; 
	 
     public WordDictionary(){
    	 root =new Node();
     }

	public void addWord(String word) {
		Node cur = root;
		for (int i = 0; i < word.length(); i++) {
			char c = word.charAt(i);
			if (cur.next.get(c) == null)
				cur.next.put(c, new Node());
			cur = cur.next.get(c);
		}
		cur.isWord = true;
	}
     public boolean search(String word){
    	 return match(root, word, 0);
     }
     private boolean match(Node node,String word,int index) {
		if(index==word.length()) 
			return node.isWord;
		char c=word.charAt(index);
		if(c!='.'){
			if(node.next.get(c)==null)
				return false;
			return match(node.next.get(c), word, index+1);
		}else{
			for (char nextChar :node.next.keySet()) {
				if(match(node.next.get(nextChar), word, index+1))
					return true;
			}
			return false;	
		}
	}
}

  

猜你喜欢

转载自www.cnblogs.com/sunliyuan/p/10742774.html