hdu2846(2009多校第四场) 字典树

明明就是个简单的字典树,我不过就是想复习一下尼玛被自己坑死了T^T

把字符串分解那儿写错了,检查了半天没找到错误,然后以为被卡数组内存,难过的学习字典树的指针写法。。

发现还是不对,大半夜突然看到自己傻乎乎的错误顿时感觉好傻逼啊啊啊!!

字典树数组写法:

 1 #include<stdio.h>
 2 #include<string.h>
 3 int flag[500005],count[500005],sz;
 4 int ch[500005][30];
 5 char s[25];
 6 void insert(char *s,int v)
 7 {
 8   int u=0,n=strlen(s),i,c;
 9   for (i=0;i<n;i++)
10   {
11     c=s[i]-'a';
12     if (!ch[u][c])
13     {
14       flag[++sz]=v;
15       count[sz]=1;
16       ch[u][c]=sz;
17     }
18     else if (flag[ch[u][c]]!=v)
19     {
20       count[ch[u][c]]++;
21       flag[ch[u][c]]=v;
22     }
23     u=ch[u][c];
24   }
25   return;
26 }
27 int find(char *s)
28 {
29   int i,u=0,len=strlen(s),c;
30   for (i=0;i<len;i++)
31   {
32     c=s[i]-'a';
33     if (!ch[u][c]) return 0;
34     u=ch[u][c];
35   }
36   return count[u];
37 }
38 int main()
39 {
40   int n,i,len,j;
41   while (~scanf("%d",&n))
42   {
43     sz=0;
44     memset(ch,0,sizeof(ch));
45     memset(count,0,sizeof(count));
46     for (i=1;i<=n;i++)
47     {
48       scanf("%s",s);
49       len=strlen(s);
50       for (j=0;j<len;j++)
51         insert(s+j,i);
52     }
53     scanf("%d",&n);
54     for (i=1;i<=n;i++)
55     {
56       scanf("%s",s);
57       printf("%d\n",find(s));
58     }
59   }
60   return 0;
61 }
View Code

指针写法:

 1 #include<stdio.h>
 2 #include<string.h>
 3 struct tree{
 4   struct tree *son[26];
 5   int count,flag;
 6 }*root;
 7 void insert(char *s,int v)
 8 {
 9   int len=strlen(s),i,j,c;
10   tree *cur=root,*next;
11   for (i=0;i<len;i++)
12   {
13     c=s[i]-'a';
14     if (cur->son[c]!=NULL) cur=cur->son[c];
15     else
16     {
17       next=new(tree);
18       for (j=0;j<26;j++)
19         next->son[j]=NULL;
20       next->count=0; next->flag=-1;
21       cur->son[c]=next;
22       cur=next;
23     }
24     if (cur->flag!=v)
25     {
26       cur->count++;
27       cur->flag=v;
28     }
29   }
30   return;
31 }
32 int find(char *s)
33 {
34   int i,len=strlen(s),c;
35   tree *cur=root;
36   for (i=0;i<len;i++)
37   {
38     c=s[i]-'a';
39     if (cur->son[c]==NULL) break;
40     cur=cur->son[c];
41   }
42   if (i<len) return 0;
43   return cur->count;
44 }
45 int main()
46 {
47   int n,i,len,j,m;
48   char s[25],st[25];
49   while (~scanf("%d",&n))
50   {
51     root=new(tree);
52     for (i=0;i<26;i++)
53       root->son[i]=NULL;
54     root->count=0; root->flag=-1;
55     for (i=1;i<=n;i++)
56     {
57       scanf("%s",s);
58       len=strlen(s);
59       for (j=0;s[j];j++)
60       {
61 //        memcpy(st,s+j,len-j);
62         insert(s+j,i);
63       }
64     }
65     scanf("%d",&m);
66     for (i=1;i<=m;i++)
67     {
68       scanf("%s",s);
69       printf("%d\n",find(s));
70     }
71   }
72   return 0;
73 }
View Code

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

转载于:https://www.cnblogs.com/xiao-xin/articles/4166245.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值