1.定义:每个样本都从头节点开始,根据前缀字符或前缀数字建立出一棵树来。没有路就新建,有就复用。
2.准备
public static int MAXN = 150001; public static int cnt = 1; public static int[][] tree = new int[MAXN][26]; public static int[] pass = new int[MAXN]; public static int[] end = new int[MAXN];
用静态数组实现前缀树,tree数组表示数的具体实现,pass数组存储路径被是使用次数,end数组表示一共有多少字符串。
功能实现:
①插入②搜索某字符串是否被插入过返回次数③返回以某一字符串为前缀的字符串的数量④删除字符串⑤清空树
public static int MAXN = 150001; public static int cnt = 1; public static int[][] tree = new int[MAXN][26]; public static int[] pass = new int[MAXN]; public static int[] end = new int[MAXN]; public static void build(){ cnt = 1; } public static void insert(String word){ int cur = 1; pass[cur]++; for(int i=0,path;i<word.length();i++){ path = word.charAt(i) - 'a'; if(tree[cur][path]==0){ tree[cur][path] = ++cnt; } cur = tree[cur][path]; pass[cur]++; } end[cur]++; } public static int search(String word){ int cur =1; for(int i=0,path;i<word.length();i++){ path = word.charAt(i) - 'a'; if(tree[cur][path]==0){ return 0; } cur = tree[cur][path]; } return end[cur]; } public static int preFixNumber(String word){ int cur = 1; for(int i=0,path;i<word.length();i++){ path = word.charAt(i) - 'a'; if(tree[cur][path]==0){ return 0; } cur = tree[cur][path]; } return pass[cur]; } public static void delete(String word){ if(search(word)>0){ int cur = 1; for(int i=0,path;i<word.length();i++){ path = word.charAt(i) - 'a'; if(--pass[tree[cur][path]]==0){ tree[cur][path] = 0; return ; } cur = tree[cur][path]; } end[cur]--; } } public static void clear(){ for(int i=0;i<=cnt;i++){ for(int j=0;j<tree[i].length;j++){ tree[i][j] = 0; } pass[i] = 0; end[i] = 0; } }