字典树(实现前缀匹配的问题)

今天听学长讲了一下字典树,收获颇丰。

举个例子,给你n个单词,每个单词的长度最大不超过len,给的顶一个长为length的长字符串,问这个字符串的前缀里包含多少个所给的单词。
先分析这道题,需要建立一个字典树将所有的单词都放到一个树里(可以看成一个不满的26叉树,每一层都是字母a~z),然后用长文本去暴力匹配这个树,记录个数。

PS:遇到题目描述中出现总单词的总长度不超过……;
或者,给定……个单词,每个单词不超过……的长度等等。
诸如此类的描述,都可以往这方面想。

字典树的操作包括建树和查找两个操作。
1.建树:
建立一个int类型二维数组ch[u][id]代表的值是当前字母的编号。其中第一维的u代表它父亲节点的编号,id代表的是哪个字母,可以写成字母的ASCII值也可以写成0~25.

int ch[n*len][26];///n为单词个数,len为单词长度
int num[n*len];///可以用来储存当前节点的子树所包含的单词数
               ///也可以记录一个单词的末位置,
               ///具体情况具体分析,此题未采用第二种;
int cnt;///用来记录字符编号
char a[len];
char s[length];
void init()
{
    memset(ch[0],0,sizeof(ch[0]));///只初始化第一层,避免超时
    cnt=0;
}

void setup(char *a,int len)
{
    int u=0;
    for(int i=0;i<len;i++)
    {
        int id=a[i]-'a';
        if(ch[u][id]!=0)
            u=ch[u][id];
        else
        {
            cnt++;
            ch[u][id]=cnt;
            ///num[cnt]++;///记录每个节点的子树包含多少单词
            memset(ch[cnt],0,sizeof(0));///用到那一层就初始化哪一层,防止超时
            u=ch[u][id];
        }
    }
    num[u]++;///插入完成之后记录末位置
}

举个例子:
字典树在这里插入图片描述
字典树每个节点是每个单词中的一个个字母。

2.查找:
用长文本字符串去遍历字典树。

int solve(char *s,int length)
{
    int u=0,ans=0;
    for(int i=0;i<length;i++)
    {
        int id=s[i]-'a';
        if(ch[u][id]==0)
            return ans;///遍历到头了,往下再也没有元素,直接返回答案
        else
        {
            u=ch[u][id];
            ans+=num[u];///未遍历到头,继续遍历,加上每个位置的单词数量
        }
    }
    return ans;
}
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值