004字符串查找---单词查找树符号表数据结构实现

本文参考《算法(第4版)》

单词查找树符号表数据结构实现

在这里插入图片描述

1.实现代码

  1. 单词查找树是字符串符号表的一种数据结构。

    单词查找树的每个节点含有一个值和一个大小为R的字符串数组,该数组存放R个链接,字符串作为该节点的键,即作为数组的索引。所以也称作R向单词查找树。每条链接指向下一个节点。如果一个字符串的尾字符对应的树中的节点的值不为空,则说明查找命中,即该树存在该字符串;如果一个字符串的尾字符对应的树中的节点的值为空,或者对应一个空链接(节点不存在),则说明查找未命中,即该树不存在该字符串。

  2. 单词查找树的主要操作有:

    查找所有的键,查找,插入,删除一个键,查找给定字符串在树中的最长键前缀,查找匹配模式字符串的所有字符串,查找以某个字符前缀的所有字符串等。


package algorithms.stringrank;

import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
import java.util.Queue;

public class TrieST<T>{
    private static int R = 256;
    private Node root;  
    public static class Node{
      private Object val;
      private Node[] next = new Node[R];
    }
    public int size(){
      return size(root);
    }
    private int size(Node x){ 
      if(x == null) return 0;
      int count = 0;    
      if(x.val != null)  count++;  
      for(char i = 0; i < R; i++) 
         count += size(x.next[i]); //每一层递归都有一个方法内局部变量count
      return count;
    }
    public T get(String key){
      Node x = get(root, key, 0);
      if(x.val == null) return null;
      return (T)x.val;
    }
    private Node get(Node x, String key, int d){
      if(x == null) return null;
      if(d == key.length()) return x; //索引d控制是否达到字符串末尾
      int c = key.charAt(d);
      return get(x.next[c], key, d+1);  
    }
    
    public void put(String key, T val){
      root = put(root, key, val, 0);
    }
    private Node put(Node x, String key, T val, int d){
      if(x == null) x = new Node(); 
      if(d == key.length()){
        x.val = val;
        return x;
      }
      int c = key.charAt(d);
      x.next[c] = put(x.next[c], key, val, d+1);
      return x;
    }
    //单词查找树中所有的字符串
    public Iterable<String> keys(){ 
      return keyWithPrefix("");
    }
    public Iterable<String> keyWithPrefix(String pre){
       Queue<String> q = new LinkedList<String>();
       collect(get(root, pre, 0), pre, q);
       return q;
    }
    private void collect(Node x, String pre, Queue<String> q){
      if(x == null) return;
      if(x.val != null) q.add(pre);
      for(char c = 0; c < R; c++) 
        collect(x.next[c], pre+c, q); 
    }
    
    //通配符匹配
    public Iterable<String> keysThatMatch(String pat){
      Queue<String> q = new LinkedList<String>();
      collect(root, "", pat, q);
      return q;
    }
    private void collect(Node x, String pre, String pat, Queue<String> q){
        int d = pre.length();
        if(x == null) return;
        if(d == pat.length() && x.val != null) q.add(pre);
        if(d == pat.length()) return;
        
        char next = pat.charAt(d);
        for(char c = 0; c < R; c++)
          if(next == '.' || next == c)
                collect(x.next[c], pre+c, pat, q);
    }
    //查找最长键前缀
    public String longestPrefixOf(String s){
      int length = search(root, s, 0, 0);
    return s.substring(0, length); 
    }
    private int search(Node x, String s, int d, int length){
      if(x == null)       return length;
      if(x.val != null)   length = d; //当前最大值
      if(d == s.length()) return length;
      
      int c = s.charAt(d);
      return search(x.next[c], s, d+1, length); 
    }
    //删除操作
    public void delete(String key){
      root = delete(root, key, 0);
    }
    private Node delete(Node x, String key, int d){
      if(x == null) return null;
      if(d == key.length()) x.val = null;
      else{ 
        char c = key.charAt(d);
        x.next[c] = delete(x.next[c], key, d+1);
      }
      
      if(x.val != null) return x; //当前节点有值不做处理
      for(char c = 0; c < R; c++)
        if(x.next[c] != null) return x; //判断当前节点是否有非空链接
      return null;
    }
  public static void main(String[] args) { 
    String[] a = new String[]{"the","air","by","them","she","shell",
         "shells","airby","shert","theme","airport","bybike"};
    Integer[] b = new Integer[]{4,5,6,7,8,9,10,1,2,3,11,12};
        
        TrieST<Integer> triest = new TrieST<Integer>();
        for(int i = 0; i < a.length; i++)
          triest.put(a[i], b[i]);
        System.out.println("the triest length: " + triest.size());
        System.out.println("airport = " + triest.get("airport"));
        
        System.out.println("打印所有的键:");
        for(String s : triest.keys())
            System.out.println(s);
        
        System.out.println("以a开头的键:");
        for(String s : triest.keyWithPrefix("a"))
            System.out.println(s);
        
        
        System.out.print("与'a..'匹配的键:");
        for(String s : triest.keysThatMatch("a.."))
            System.out.println(s);
        System.out.print("与'them.'匹配的键:");
        for(String s : triest.keysThatMatch("them."))
            System.out.println(s); 
        
        System.out.print("airport的最长键:");
        for(String s : triest.keysThatMatch("airport")){
          System.out.println(s);
        }
        System.out.print("bybikes的最长键:");
        for(String s : triest.keysThatMatch("bybike")){
          System.out.println(s);
        }
        
        System.out.println("删除键'airby'后:");
        triest.delete("airby");
        for(String s : triest.keys())
            System.out.println(s);
        System.out.println("删除键'theme'后:");
        triest.delete("theme");
        for(String s : triest.keys())
            System.out.println(s);
  } 
}

输出:

the triest length: 12
airport = 11
打印所有的键:
air
airby
airport
by
bybike
she
shell
shells
shert
the
them
theme
以a开头的键:
air
airby
airport
与'a..'匹配的键:air
与'them.'匹配的键:theme
airport的最长键:airport
bybikes的最长键:bybike
删除键'airby'后:
air
airport
by
bybike
she
shell
shells
shert
the
them
theme
删除键'theme'后:
air
airport
by
bybike
she
shell
shells
shert
the
them

2.总结

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值