快速存储和查找字符串的一种数据结构。
在算法比赛中,如果有使用结构体的数据结构一般不采用工程中的用结构体创立释放而是使用了数组模拟的方式来创建。因为结构体在新建的时候需要使用new函数,这个函数非常的浪费时间,而比赛一大考量是时间复杂程度。
在使用数组模拟中,为了模拟地址的存储方式,一般会设置一个一只递增的idx变量来表示一位数组和二维数组的地址。
插入的语言描述:先创立一个模拟指针(位数指针),在遍历存入的时候先将字符串中的每一个字符都转化为数字,查询是否存在这个字符对应的位数指针,如果不存在那么就新建一个位数指针,使用idx来表示位数指针(++idx)【如果写一个idx++那么第一行和第二行会重复】模拟每一位数字的对应,如果存在的话就让指针位移到现在存储到的相对应的二维数组的存储值(也就是下一行)。最后在遍历完的时候给cnt来记录到哪里结束,防止有前面相同(如abc和abcde)的字符串在abcd的时候返回正确或者存了abcde存在abc不存在却返回abc存在。

图片出自csdn的 四谷夕雨 ,。这里当作博客笔记的复习资料帮助我自己理解。
可以从图片中的例子来发现idx的重要作用,在1的左半部树遍历完后,右边的1半部插入的idx不会变回,二维数组中存储的值会让指针指到正确的行,不会重新回到左半边。但是如果是相同行数的相同字符仍然可以在当前分支往下。很精妙。
在查找的时候和输入类似,定义一个指针从0开始,看看查找字符的字符串是否存在于其中,如果存在那么就把指针调整到下一位,不存在就直接return 0,如果一直到了最后,那么就就返回cnt【p】看一下这里是不是存在是以该字符结尾的字符串。
#include<iostream>
using namespace std;
const int N=100010;
int trie[N][26],cnt[N];
char q[N];
int idx=0;
void insert(char q[]){
int p=0;//相当于一个空指针
for(int i=0;q[i];i++){
int u=q[i]-'a';
if(!trie[p][u]) trie[p][u]=++idx;
p=trie[p][u];
}
cnt[p]++;
}
int query(char q[]){
int p=0;
for(int i=0;q[i];i++){
int u=q[i]-'a';
if(!trie[p][u]) return 0;
p=trie[p][u];
}
return cnt[p];
}
int main()
{
int n;
cin >> n;
while(n--){
char judge[2];
cin >> judge >> q;
if(*judge=='I') insert(q);
else if(*judge=='Q') printf("%d\n",query(q));
}
return 0;
}
本文介绍了如何在算法竞赛中通过数组模拟结构体,避免new函数的时间消耗,重点讲解了位数指针(idx)在模拟字符串存储和查找中的关键作用,以及插入和查询操作的实现。
1363

被折叠的 条评论
为什么被折叠?



