前缀树(PE树)

笔记

736be1b0624318b971c2e2b4dd12539d

delete方法我的写法

   public void delete(String word){
// 我写之前还有困惑,万一要删除的根本就没加入过怎么办?我的想法是边找边减,但问题是减到最后如果发现确实不存在,要如何还原之前的改动??于是我直接忽略了这个想法,不管这种情况。
        int cur = 1;
        int next = 0;
        pass[cur]--;
        for(int i = 0,path;i < word.length();++i){
            path = word.charAt(i) - 'a';
            next = tree[cur][path];
            pass[next]--;
            cur = next;
        }
        end[cur]--;
// 每次寻找路径,pass--,到最后end--/但这样写,到最后判断路径是否需要删除时写不下去了。因为cur已经被next覆盖,不知道如何删除树。
        if(pass[cur] == 0){
            
        }
    }

神的写法

	public static void delete(String word) {
		if (search(word) > 0) {// 先看存不存在,再删除
			int cur = 1;
			pass[cur]--;
			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]--;
		}
	}

题目

题目

最终代码

import java.io.*;
import java.util.Arrays;


// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static int MAXN = 150001;
    public static int[][] tree = new int[MAXN][26];
    public static int[] pass = new int[MAXN];
    public static int[] end = new int[MAXN];
    public static int cnt = 0;

    public static void build() {
        cnt = 1;
    }

    public static void insert(String word) {
        int cur = 1;
        int next = 0;
        pass[cur]++;
        for (int i = 0, path; i < word.length(); ++i) {
            path = word.charAt(i) - 'a';
            if (tree[cur][path] == 0) {
                next = ++cnt;
            } else {
                next = tree[cur][path];
            }
            pass[next]++;
            tree[cur][path] = next;
            cur = next;
        }
        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 pre) {
        int cur = 1;
        for (int i = 0, path; i < pre.length(); ++i) {
            path = pre.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;
            int next = 0;
            pass[cur]--;
            for (int i = 0, path; i < word.length(); ++i) {
                path = word.charAt(i) - 'a';
                next = tree[cur][path];
                if (--pass[next] == 0) {
                    tree[cur][next] = 0;
                }
                cur = next;
            }
            end[cur]--;
        }


    }
    public static void clear() {
        for (int i = 1; i <= cnt; i++) {
            Arrays.fill(tree[i], 0);
            end[i] = 0;
            pass[i] = 0;
        }
    }
    public static int m, op;

    public static String[] splits;

    public static void main(String[] args) throws IOException {
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
        String line = null;
        while ((line = in.readLine()) != null) {
            build();
            m = Integer.valueOf(line);
            for (int i = 1; i <= m; i++) {
                splits = in.readLine().split(" ");
                op = Integer.valueOf(splits[0]);
                if (op == 1) {
                    insert(splits[1]);
                } else if (op == 2) {
                    delete (splits[1]);
                } else if (op == 3) {
                    out.println(search(splits[1]) > 0 ? "YES" : "NO");
                } else if (op == 4) {
                    out.println(prefixNumber(splits[1]));
                }
            }
            clear();
        }
        out.flush();
        in.close();
        out.close();
    }

}
## debug
第一次输出全是No和0.应该是insert有问题,debug发现tree没有更新,原来是没有赋值tree[cur][path];
之前所有的变量和方法都是静态的。
posted @ 2025-09-20 15:33  MineralWaterAndCola  阅读(3)  评论(0)    收藏  举报