trie树
trie树即为对每个字符串出现的字母进行插入操作使其形成一个树状结构
例如:当我们要插入{abcd,dcb,bcd,ac}时,其形成的树状结构为
由于每个不同的字符串的相同的字母所在的位置不同,则每个字母的节点数也不同,因此当前以节点为下标的字母出现的次数即为以该字母结尾的字符串的出现次数
上代码:
1 #include<iostream> 2 using namespace std; 3 const int N=100010; 4 int son[N][26];//由于插入的是字符串,则每个字母都可以映射到0-25之间的值,存入的是当前节点指向的下一个节点的下标 5 int idx,cnt[N];//idx控制插入的是第几个字母,和链表的idx作用相同,cnt计数每个字符串出现的次数 6 char str[N];//读入字符串 7 void insert(char str[]) 8 { 9 int u=0; 10 for(int i=0;str[i];i++)//从0遍历整个字符串 11 { 12 int k=str[i]-'a';//字符串每个字母映射成数字 13 if(!son[u][k]) son[u][k]=++idx;//如果当前节点的子节点没有该字母,即没有该字符串则创建一个该字母的节点 14 u=son[u][k];//从该字母节点继续查找 15 } 16 cnt[u]++;//该字母的节点数加1,即以该字母结尾的字符串的次数加1 17 } 18 int query(char str[]) 19 { 20 int u=0; 21 for(int i=0;str[i];i++) 22 { 23 int k=str[i]-'a'; 24 if(!son[u][k]) return 0;//如果没有找到该字母,则说明没有该字符串,则返回0 25 u=son[u][k]; 26 } 27 return cnt[u];//返回该字符串的出现次数 28 } 29 int main() 30 { 31 int n; 32 cin>>n; 33 while(n--) 34 { 35 char op[2]; 36 scanf("%s%s",op,str);//不能用%c读入操作,因为%c可以识别空格不会停止读入 37 if(op[0]=='I') insert(str); 38 else printf("%d\n",query(str)); 39 } 40 return 0; 41 }