hdu 2846

本文介绍了一种改进型字典树的实现方法,通过在每个节点增加一个标记来避免重复计数,适用于查找字符串前缀的应用场景。文章提供了详细的C语言实现代码,并展示了如何通过拆分单词构建树形结构,以及如何查询特定字符串出现的次数。

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

字典树的变形,常规字典树用来求前缀的,所以把每个单词拆成len个词建树,为了避免abab这样的查ab时会出现两次,每次加一个标记,如果该节点上次的建树的单词与本次相同就不更新,否则更新




#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct tree
{
	struct tree *son[26];
	int count;
	int flag;
}*root;
void insert(char *p,int id)
{
	int i,k,j;
	tree *cur=root,*next;
    int len=strlen(p);
	for(i=0;i<len;i++)
	{
		k=p[i]-'a';
		if(cur->son[k]!=NULL)
			cur=cur->son[p[i]-'a'];
		else 
		{
			next=new(tree);
			for(j=0;j<26;j++)
				next->son[j]=NULL;
			next->count=0;
			next->flag=-1;
			cur->son[p[i]-'a']=next;
			cur=next;
		}
		if(cur->flag!=id)//如果上次在该节点更新的单词与本次单词不同就更新
		{
			cur->count++;	
			cur->flag=id;
		}
	}	
}
int find(char *p)  
{  
    int i;  
    tree *cur=root;  
    int len=strlen(p);  
    for(i=0;i<len;i++)  
    {  
        int k=p[i]-'a';  
        if(cur->son[k]==NULL)  
            break;  
        else cur=cur->son[k];  
    } 
	if(i<len) return 0;
	return cur->count;  
}  
int main()
{
	int i,j,n,m;
	char s[25];
	root=new(tree);  
	for(i=0;i<26;i++)
		root->son[i]=NULL;
	root->count=0;
	root->flag=-1;
	scanf("%d",&n);
	for(i=1;i<=n;i++)
	{
		scanf("%s",s);
		for(j=0;s[j];j++)
		{
			insert(s+j,i);//拆单词建树
		}
	}
	scanf("%d",&m);
	while(m--)
	{
		scanf("%s",s);
		j=find(s);
		printf("%d\n",j);
	}
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值