UVa 11732 strcmp()函数(左孩子右兄弟表示法)

本文介绍了一种使用Trie树进行字符串匹配的方法,并详细展示了插入字符串到Trie树的过程及如何通过深度优先搜索计算匹配数量。代码示例中包含了初始化Trie树、插入字符串、递归遍历树节点等功能。

 

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<string>
 4 #include<cstring>
 5 #include<vector>
 6 using namespace std;
 7 
 8 const int maxn = 4000 * 1000 + 10;
 9 int n;
10 long long ans;
11 
12 struct Trie
13 {
14     int head[maxn];     //head[i]为第i个结点的左儿子编号
15     int next[maxn];     //next[i]为第i个结点的右兄弟编号
16     char ch[maxn];      //第i个结点上的字符
17     int tot[maxn];
18     int sz;
19 
20     void init()
21     {
22         sz = 1;
23         head[0] = tot[0] = next[0] = 0;
24     }
25 
26     void insert(char *s)
27     {
28         int u = 0, v, n = strlen(s);
29         tot[0]++;
30         for (int i = 0; i <= n; i++)
31         {
32             bool found = false;
33             for (v = head[u]; v != 0; v = next[v])
34             {
35                 if (ch[v] == s[i])
36                 {
37                     found = true;
38                     break;
39                 }
40             }
41             if (!found)
42             {
43                 v = sz++;
44                 tot[v] = 0;
45                 ch[v] = s[i];
46                 next[v] = head[u];
47                 head[u] = v;
48                 head[v] = 0;
49             }
50             u = v;
51             tot[u]++;
52         }
53     }
54 
55     void dfs(int depth, int u)
56     {
57         if (head[u] == 0)
58             ans += tot[u] * (tot[u] - 1)*depth;
59         else
60         {
61             int sum = 0;
62             for (int v = head[u]; v != 0; v = next[v])
63                 sum += tot[v] * (tot[u] - tot[v]);
64             ans += sum / 2 * (2 * depth + 1);
65             for (int v = head[u]; v != 0; v = next[v])
66                 dfs(depth + 1, v);
67         }
68     }
69 }t;
70 
71 int main()
72 {
73     //freopen("D:\\txt.txt", "r", stdin);
74     char str[1005];
75     int kase = 0;
76     while (~scanf("%d", &n), n)
77     {
78         t.init();
79         while (n--)
80         {
81             scanf("%s", str);
82             t.insert(str);
83         }
84         ans = 0;
85         t.dfs(0,0);
86         printf("Case %d: %lld\n", ++kase, ans);
87     }
88     return 0;
89 }

 

转载于:https://www.cnblogs.com/zyb993963526/p/6642418.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值