杭电1251——统计难题(字典树的应用)

本文介绍了一种使用字典树(Trie)进行高效前缀查询的方法。通过建立字典树并统计每个节点的前缀出现次数,可以快速查询任意给定前缀的出现频率。文章提供了完整的C语言实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1251

主要算法:
该题运用了字典树的知识。输入单词时,建立字典树。每个节点的v的值代表从根节点到该节点路径上所有字母组成的前缀出现的次数。当输入前缀时,只需查找字典树中是否有该前缀,若有,输出前缀的最后一个字母的v 的值,若无,输出0.

AC代码:

# include<stdio.h>
# include<string.h>
# include<malloc.h>
# define MAX 26

typedef struct Trie{
    struct Trie *next[MAX];
    int v;//记录以该节点为最后一个字母的前缀出现的次数
}Trie;

Trie * root=NULL;

void insertTrie(char words[]);
void createTrie();
int search(char perfix[]);

int main()
{
    createTrie();
    char perfix[10];
    while(scanf("%s",perfix)!=EOF)
    {
        printf("%d\n",search(perfix));
    }
    return 0;
}

//建立字典树
void createTrie()
{
    int i;
    char words[12];
    if(!root)
        root=(Trie *)malloc(sizeof(Trie));
    for(i=0;i<MAX;i++)
        root->next[i]=NULL;
    root->v=0;
    while(gets(words)&&strcmp(words,"\0")!=0)//gets()函数读入整行数据,并且将'\n'换成'\0'
    {
        insertTrie(words);
    }

}

//将单词插入字典树中
void insertTrie(char words[])
{
    Trie *p=root;
    int len=strlen(words),i,j;
    for(i=0;i<len;i++)
    {
        int id=words[i]-'a';
        if(p->next[id]==NULL)//该层上不存在‘a’+id的节点,新建,并且置v=1
        {
            p->next[id]=(Trie *)malloc(sizeof(Trie));
            p=p->next[id];
            p->v=1;
            for(j=0;j<MAX;j++)
                p->next[j]=NULL;
        }
        else
        {
            p=p->next[id];
            (p->v)++;
        }
    }
}

//在字典树中查询是否存在前缀
int search(char perfix[])
{
    Trie *p=root;
    int len=strlen(perfix),i;
    for(i=0;i<len;i++)
    {
        int id=perfix[i]-'a';
        if(p->next[id]==NULL)
            break;
        p=p->next[id];
    }
    if(i<len)
        return 0;
    else
        return p->v;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值