hdu 1251 字符串前缀 子典树

今天找了一道关于Tire的问题,题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1251

处理关于前缀出现次数的问题,定义结点存放分支的个数,依次往下循找,如果合理,则返回分支个数否则返回零。

    /****************************华丽的分割线~~**********************************/

 字典树又称单词查找树,是一种树形结构,哈希树的变种,典型应用是用于统计,排序和保存大量的字符串,类似于字典的结构,它的优点是利用字符串的公共前缀来节约存储空间,最大限度的减少无谓的字符串比较,查询效率比哈希表高.

基本性质:

 根结点不包括任何字符,除此之外,每个节点对应一个字符,从根结点出发,路径上经过的字符连接起来,为该节点对应的字符串,每个节点有多个子节点.

基本操作:

常见的有插入,查找,修改.

实现过程:

我们可以根据查字典的方法来进行查找和修改操作.

第一步:对根节点的子节点与需要查询的字符串首字母(即首关键码)进行匹配,正如我们要查询love这个单词,首先限定的范围即是由'l'开头的.

第二步:在相应的子树上,取的第二个关键码,如果为love,这里即为'o'.

第三步:重复第二步的递归.

第四步:若所以关键码被查询完,则可以读取相应的信息,本题信息为出现的次数.

Ac code:

#include<iostream>
#include<stdio.h>
#include<cstdio>
using namespace std;
struct node
{
 int branchs;      //info 出现的次数
 node *next[26];   //字符种类n,即子节点的个数
};
void insert(char s[],node *T) //插入操作
{
 int i=0,k,j;
 node *p,*q;
 p=T;
 while(s[i])
 {
  k=s[i]-'a';         //求出关键码的位置
  if(p->next[k]==NULL)       //如果此位置原先为空,则加入该字符,并出现次数加1
  {
   q=new node; 
   q->branchs=1;        //置为1
   for(j=0;j<26;++j)    //结点的初始化
   q->next[j]=NULL;          
   p->next[k]=q;         插入该节点
  }
  else
  p->next[k]->branchs++;   //出现过,则次数加1
  p=p->next[k];      //往下级检索
  ++i;      
 }
}

int search(char s[],node *T)
{
 int i=0,ans,k;
 node *p=T;
 if(p==NULL) return 0;
 while(s[i])
 {
  k=s[i]-'a';
  if(p->next[k]==NULL) return 0;       //往下循找为空,则不符合,直接返回零
  ans=p->next[k]->branchs;
  p=p->next[k];
  ++i;
 }
 return ans;
}
int main()
{
 node *T=new node;
 T->branchs=0;           //初始,根节点不包括任何字符
 int j;
 char s[11];
 for(j=0;j<26;++j) T->next[j]=NULL;
 while(gets(s))       //gets为c语言函数
 {
 if(s[0]=='\0') break;
 insert(s,T);
    }
 while(gets(s)!=NULL)
 printf("%d\n",search(s,T));
// system("pause");
 return 0;
}
 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值