UVA 11732 链式字典树
来源:互联网 发布:松下plc编程手册 编辑:程序博客网 时间:2024/05/21 10:16
题意
给一些字符串,问如果使用strcmp函数对这些字符串两两比较,需要进行多少次字符比较。(strcmp函数在题目中已给出,如果字符相等,则还需要将该字符与’\0’进行比较)
题解
链式字典树我自己的叫法,网上大多数题解都把这种字典树叫做左儿子,右兄弟的字典树,但是这种叫法感觉会引起误解。一开始我以为右兄弟是根的兄弟,后来才意识到右兄弟是左儿子的兄弟。
具体效果见下图。
可以看到,这样存储只需要开节点个数大小的数组就可以了,不需要再开一个二维数组,从而节省了大量空间。对于这道题来说,所需的数组空间直接降了1.5个数量级,效果是非常明显的。
至于链式字典树的存储方式,可以用链表,也可以用数组模拟链表。这里我选择用数组模拟链表来避免指针操作。
v=sz++;c[v]=st[i];val[v]=0;son[v]=0;nex[v]=son[u];son[u]=v;
上述代码是链式字典树增加节点的过程,由于链式字典树本身的数组无法记录节点对应的字符信息,所以需要增加一个字符记录数组,也就是C。val用来记录节点值,在本题中用来记录访问次数。nex对应上图中的next,son对应上图中的son1。
通过链式字典树解决了存储空间的问题以后,本题就算解决一半了。另一半是统计比较次数。对于普通字符(除了’\0’以外),每次字符比较都会比较两次,调用字符比较的次数就是val[u]值(u表示将字符串插入字典树过程中访问的节点)。如果一直比较到结尾还没有分出大小,那么还会额外针对’\0’比较两次,这时候就需要+cnt[u]。(u代表末尾节点)如果在比较过程中分出了大小,还需要再加1次,因为最后一次不相等的比较没有计算。
最后将所有计算得到的值累加起来就是所求的总比较次数。
代码
#include <iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<vector>#include<cmath>#include<queue>#include<string>#include<set>#include<map>#include<bitset>#include<stack>#include<string>#define UP(i,l,h) for(int i=l;i<h;i++)#define DOWN(i,h,l) for(int i=h-1;i>=l;i--)#define W(a) while(a)#define MEM(a,b) memset(a,b,sizeof(a))#define LL long long#define INF 0x3f3f3f3f#define MAXN 100010#define MOD 1000000009#define EPS 1e-10using namespace std;int ch[4000010];int val[4000010],nex[4000010],son[4000010],cnt[4000010];char c[4000010];char st[1010];int sz;LL ans;int getNum(char c) { if(c>='0'&&c<='9') { return c-'0'; } else if(c>='a'&&c<='z') { return c-'a'+10; } else if(c>='A'&&c<='Z') { return c-'A'+36; }}void insert() { int u=0; int len=strlen(st); ans+=val[0]; val[0]++; UP(i,0,len) { int v; for(v=son[u];v!=0;v=nex[v]){ if(c[v]==st[i]){ break; } } if(!v) { v=sz++; c[v]=st[i]; val[v]=0; son[v]=0; nex[v]=son[u]; son[u]=v; } u=v; ans+=val[u]*2; val[u]++; } if(cnt[u]){ ans+=cnt[u]; } cnt[u]++;}int main() { int n; int ks=1; W(~scanf("%d",&n)) { if(n==0) break; MEM(ch,0); MEM(val,0); MEM(nex,0); MEM(son,0); MEM(cnt,0); MEM(c,0); ans=0; sz=1; UP(i,0,n) { scanf("%s",st); insert(); } printf("Case %d: %lld\n",ks++,ans); }}/*3abcabcabc*/
阅读全文
0 0
- UVA 11732 链式字典树
- UVA 11732 - strcmp() Anyone? 字典树
- UVA 11732 strcmp() Anyone?(字典树Trie)
- uva 11732 strcmp() Anyone? 字典树
- uva 11732 - strcmp() Anyone?(字典树)
- UVA 11732 "strcmp()" Anyone?(字典树)
- Uva 11732 "strcmp()" Anyone? (字典树)
- uva 11732 "strcmp()" Anyone?(字典树)
- UVA 11732 mark这个字典树模版
- UVA 12937 字典树
- uva 11488 字典树
- UVA 11488 字典树
- UVA 12506(字典树)
- UVa 1401 字典树+DP
- UVA - 11732 "strcmp()" Anyone? (字典树的处理)
- 字典树(strcmp()函数,uva 11732)
- UVA 11732 "strcmp()" Anyone? 字典树(数组实现)
- UVA - 11732 依旧是字典树板子,和左儿子右兄弟法字典树
- 2018网易校招内推编程题 小易喜欢的数列(动态规划)
- 在ubuntu根文件系统上安装lxde桌面
- POJ
- Junit测试maven+ssm项目的过程及出现的错误总结
- block,inline和inline-block概念和区别
- UVA 11732 链式字典树
- 【JavaScript】alert()confirm() prompt()
- DrawerLayout实现侧拉索引
- 无题 stl 二分
- 剑指offer(2):替换空格
- iOS如何设置按钮左文字右图片
- soj3172Fisherman_01背包装满
- @javax.annotation.Resource的使用以及和@Autowired的区别
- Spring注入中byType和byName的总结