Trie树

97 阅读1分钟
  • Trie字典树又叫前缀树(prefix tree)

  • 高效地存储和查找字符串集合的数据结构

  • 在每个字符串的结尾打上标记

Snipaste_2023-03-04_13-02-52.png

模板

  • C++
int son[N][26], cnt[N], idx;
// 0号点既是根节点,又是空节点
// son[][]存储树中每个节点的子节点
// cnt[]存储以每个节点结尾的单词数量

// 插入一个字符串
void insert(char *str)
{
    int p = 0;
    for (int i = 0; str[i]; i ++ )
    {
        int u = str[i] - 'a';
        if (!son[p][u]) son[p][u] = ++ idx;
        p = son[p][u];
    }
    cnt[p] ++ ;
}

// 查询字符串出现的次数
int query(char *str)
{
    int p = 0;
    for (int i = 0; str[i]; i ++ )
    {
        int u = str[i] - 'a';
        if (!son[p][u]) return 0;
        p = son[p][u];
    }
    return cnt[p];
}
  • Java
public static int[][] son = new int[N][26];
public static int[] cnt = new int[N];
public static idx = 0;

public static void insert(String str) {
    int p = 0;
    for (int i = 0; i < str.length(); i++) {
        int u = str.charAt(i) - 'a';
        if (son[p][u] == 0) {
            son[p][u] = ++idx;
        }
        p = son[p][u];
    }
    cnt[p]++;
}

public static int query(String str) {
    int p = 0;
    for (int i = 0; i < str.length(); i ++) {
        int u = str.charAt(i) - 'a';
        if (son[p][u] == 0) {
            return 0;
        }
        p = son[p][u];
    }
    return cnt[p];
}

练习

01 Trie字符串统计

  • 题目

Snipaste_2023-03-04_20-37-25.png

  • 题解
import java.io.*;

public class Main {
    public static final int N = 100010;
    public static int[][] son = new int[N][26];
    public static int[] cnt = new int[N];
    public static int idx = 0;
    public static int n;

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        PrintWriter pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
        n = Integer.parseInt(br.readLine());
        while (n-- > 0) {
            String[] str1 = br.readLine().split(" ");
            if (str1[0].equals("I")) {
                insert(str1[1]);
            } else {
                pw.println(query(str1[1]));
            }
        }
        pw.close();
        br.close();
    }

    public static void insert(String str) {
        int p = 0;
        for (int i = 0; i < str.length(); i++) {
            int u = str.charAt(i) - 'a';
            if (son[p][u] == 0) {
                son[p][u] = ++idx;
            }
            p = son[p][u];
        }
        cnt[p]++;
    }

    public static int query(String str) {
        int p = 0;
        for (int i = 0; i < str.length(); i++) {
            int u = str.charAt(i) - 'a';
            if (son[p][u] == 0) {
                return 0;
            }
            p = son[p][u];
        }
        return cnt[p];
    }
}

02 最大异或对

  • 题目
    • 异或:不进位加法

Snipaste_2023-03-04_20-38-29.png

  • 题解
import java.io.*;

public class Main {
    public static final int N = 3100010;
    public static int[][] son = new int[N][2];
    public static int idx = 0;
    public static int n;

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        PrintWriter pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
        n = Integer.parseInt(br.readLine());
        String[] str1 = br.readLine().split(" ");
        for (int i = 0; i < n; i++) {
            insert(Integer.parseInt(str1[i]));
        }
        int res = 0;
        for (int i = 0; i < n; i++) {
            res = Math.max(res, query(Integer.parseInt(str1[i])));
        }
        pw.println(res);
        pw.close();
        br.close();
    }

    public static void insert(int a) {
        int p = 0;
        for (int i = 30; i >= 0; i--) {
            int u = a >> i & 1;
            if (son[p][u] == 0) {
                son[p][u] = ++idx;
            }
            p = son[p][u];
        }
    }

    public static int query(int a) {
        int p = 0, res = 0;
        for (int i = 30; i >= 0; i--) {
            int u = a >> i & 1;
            if (son[p][1 - u] != 0) {
                res += 1 << i;
                p = son[p][1 - u];
            } else {
                p = son[p][u];
            }
        }
        return res;
    }
}