-
Trie字典树又叫前缀树(prefix tree)
-
高效地存储和查找字符串集合的数据结构
-
在每个字符串的结尾打上标记
模板
- 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字符串统计
- 题目
- 题解
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 最大异或对
- 题目
- 异或:不进位加法
- 题解
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;
}
}