【模版】trie树
程序员文章站
2022-05-19 18:55:23
...
trie树
字符串树,多叉树。
每个结点保存的是单个字符,结点按从小到大的顺序编号。
对有公共前缀的若干组字符串,公共部分不用建立多余结点。
有插入和查询两种操作。代码很好记也很好理解。
算法流程:
整型二维数组 。赋值 为 结点数。
插入:
对于要插入的字符串 。从前往后处理:判断当前字符有没有被记录过,如果没有被记录,则增加结点并记录(如果被记录过,即与之前插入的字符串有公共前缀,则不用增加结点)。然后跳到下一个结点处理下一个字符。
字符串 的最后一个字符对应结点编号一定要标记,表示当前字符串结束。
void Insert()
{
char key[1100];
scanf("%s",key);
int len = strlen(key), k = 0;
for(int i = 0; i < len; i++)
{
int c = key[i] - 'a';
if(!trie[k][c]) trie[k][c] = ++t;
k = trie[k][c];
}
flg[k] = 1;
}
查询:
同插入一样,对字符串 从前往后处理,判断当前位置的字符有没有提前被编号,如果没有则说明字符串 尚未被插入。如果有被编号,则挪动至下一个结点继续查找下一个字符。
查询到最后一个字符时,需要判断当前的结点是否是 之前插入的字符串的结尾字符。(防止出现 当前查询的字符串 是 之前插入字符串的前缀的情况)
下列代码为例题的代码。
int Query()
{
char key[1100];
scanf("%s",key);
int len = strlen(key), k = 0;
for(int i = 0; i < len; i++)
{
int c = key[i] - 'a';
if(!trie[k][c]) return 0;
k = trie[k][c];
}
if(flg[k] == 0) return 0;
cnt[k]++;
return cnt[k];
}
例题:于是他错误的点名开始了
其他trie树题目:
[USACO08DEC]Secret Message G
[TJOI2010]阅读理解
上一篇: 【模版】trie树