字典树习题

http://acm.hdu.edu.cn/showproblem.php?pid=1251

hdu1251

题意:先几个单词空一行再给几个前缀,判断每个前缀在单词中出现的次数

做法:设置count在字典树中,对于字符串,走到每个字符时都把count ++。查找到时候,如果未走到头就是1,走到头了就是count

链表版本

//字典树,根节点不算
//字典树第一发,g++超内存。c++不超
#include<cstdio>
#include<cstring>
#include <iostream>
using namespace std;
struct node
{
    node *nexta[26];
    int countx;
    node()
    {
        memset(nexta,NULL,sizeof(nexta));
        //memset(nexta,NULL,sizeof(nexta));
        countx = 0;
    }
};
node *p,*root = new node();
void build(char a[])
{
    p = root;
    int t,l = strlen(a);
    for(int i = 0;i < l; i++)
    {
        t = a[i] - 'a';
        if(p->nexta[t] == NULL)
        {
            p->nexta[t] = new node();
        }
        p = p -> nexta[t];
        p->countx ++;
    }
}
int findx(char a[])
{
    p = root;
    int t,l = strlen(a);
    for(int i = 0; i < l; i ++)
    {
        t = a[i] - 'a';
        if(p->nexta[t] == NULL)
        {
            return 0;
        }
        p = p ->nexta[t];
    }
    return p -> countx;
}
int main()
{
    //freopen("in.txt","r",stdin);
    char s[11];
    while(gets(s) && strlen(s))
    {
        build(s);
    }
    while(gets(s) && strlen(s))
    {
        printf("%d\n",findx(s));
    }
    return 0;
}
数组版本

//字典树,根节点不算
//字典树,数组版本。注意根节点要在建树之前清零
#include<cstdio>
#include<cstring>
#include <iostream>
using namespace std;
struct node
{
    int nexta[26];
    int countx;

}f[1000000];
void init(int a)//新增函数
{
        memset(f[a].nexta,-1,sizeof(f[a].nexta));
        f[a].countx = 0;
}
int cnt = 1;
void build(char a[])
{
    int p = 0;
    int t,l = strlen(a);
    for(int i = 0;i < l; i++)
    {

        t = a[i] - 'a';
        if(f[p].nexta[t] == -1)
        {
            f[p].nexta[t] = cnt;
            init(cnt);
            cnt++;
        }
        p = f[p].nexta[t];
        f[p].countx ++;
    }
}
int findx(char a[])
{
    int k = 0;
    int t,l = strlen(a);
    for(int i = 0; i < l; i ++)
    {
        t = a[i] - 'a';
        k = f[k].nexta[t];
        if(k == -1)
            return 0;
    }
    return f[k].countx;
}
int main()
{
    //freopen("in.txt","r",stdin);
    char s[11];
    init(0);//注意根节点要先清零
    while(gets(s) && strlen(s))
    {
        build(s);
    }
    while(gets(s) && strlen(s))
    {
        printf("%d\n",findx(s));
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值