hdu-1251-Trie(字典树)

这个题要查询是以某个串为前缀的串的个数

那么我们可以利用val数组,初始为0,然后每次插入一个字符串的时候就令该串的所有节点val值+1

最后要查询的串的最后一个字符所对应的编号的val值就是以查询串为前缀的串的个数

这里再说下字典树的ch[i][j]记录的是编号为i的节点的子节点j的编号

比如说ab这个串,当a编号是7时,ch[7][‘b’-‘a’]储存的就是b的编号

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <vector>
#include <stack>

using namespace std;

const int N=1000000+5;
int ch[N][30];
char s[12];
int val[N];
int sz,ans;

int idx(char c)
{
    return c-'a';
}

void Inser(char *s)
{
    int u=0,n=strlen(s);//每次从根节点开始
    for(int i=0;i<n;i++)
    {
        int c=idx(s[i]);
        if(!ch[u][c])//如果有新的节点
        {
            memset(ch[sz],0,sizeof(ch[sz]));
            ch[u][c]=sz++;//新节点的编号
        }
        u=ch[u][c];//沿着当前串向下走
        val[u]++;//用过一次就增加一次
    }
}

int Find(char *s)//为了找到查询串的最后那个字符的编号
{
    int u=0,n=strlen(s),c;
    for(int i=0;i<n;i++)
    {
        c=idx(s[i]);
        u=ch[u][c];
        if(!u) return 0;//这个地方要注意判断是否有这个前缀
    }
    return val[u];
}

void ini()
{
    sz=1;
    memset(ch[0],0,sizeof(ch[0]));
    memset(val,0,sizeof(val));
}

int main()
{
    ini();
    while(gets(s) && s[0]>='a' && s[0]<='z') Inser(s);
    while(gets(s))
    {
        ans=0;
        printf("%d\n",Find(s));
    }
    return 0;
}

 

    原文作者:Trie树
    原文地址: https://blog.csdn.net/alusang/article/details/81625790
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞