最近在上计算机应用编程,老师给了一个大小为900MB的含20000000行邮箱地址的文件。 然后再给出了1000条查询数据,让你用字典树建树然后查询是否出现过。

试了下普通的tire树,特意用二进制写了下,结果才建了300000的时候就快用了2G内存,根本不行。

后面学习了下 PAT trie,发现确实是好东西,已经几乎达到最优内存了,如果有N个记录,那么只需要2*N个节点即可建成字典树。

算法的关键在于先将记录用一串二进制位表示,然后在建树的时候只在一些具有区别作用的二进制位进行节点分裂。

具体见http://hxraid.iteye.com/blog/615295,这篇博客讲的比较详细。

这里给出我用C++实现的代码。

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <stdlib.h>
#include <math.h>
using namespace std;
#define MAXLEN 1000000000LL
#define N 20020000
struct node
{
int l,r;
int pos;
bool flag;//用来标记是否是叶子节点
int end_point;//指向叶子节点.
}g[*N]; char saveword[MAXLEN];
int word_pos[N];
short int word_len[N];
int n;
char str[];
int len;
int cnt;
char qest[][];
bool flag_ans[]; void build_tree(int s,int head)
{
if(g[head].flag==)//表示叶子结点
{
int tn=g[head].end_point;
int num=(s>>);
int other=(s&);
int ta,tb;
while()
{
if(num>=len) break;
ta=(str[num]&(<<(-other)) );
tb=(saveword[(word_pos[tn]+num)]&(<<(-other)));
if( ta!=tb )
{
//开始分裂
g[cnt]=g[head];
cnt++;
g[head].flag=;
g[head].pos=(num<<)+other;
if(tb==)
g[head].l=cnt-;
else g[head].r=cnt-;
g[cnt].end_point=n;
g[cnt].flag=;
cnt++;
if(ta!=)
g[head].r=cnt-;
else g[head].l=cnt-;
break;
}
other++;
if(other==)
{
num++;
other=;
}
}
}
else
{
int tn=g[head].end_point;
int tpos=g[head].pos;
int num;
int other;
int ta,tb;
for(int i=s;i<tpos;i++)
{
num=(i>>);
other=(i&);
ta=(str[num]&(<<(-other)) );
tb=(saveword[(word_pos[tn]+num)]&(<<(-other)));
if(ta!=tb)//ta!=tb
{
g[cnt]=g[head];
cnt++;
g[head].flag=;
g[head].pos=i;
if(tb!=)
g[head].r=cnt-;
else g[head].l=cnt-;
g[cnt].flag=;
g[cnt].end_point=n;
cnt++;
if(ta!=) g[head].r=cnt-;
else g[head].l=cnt-;
return ;
}
}
num=(tpos>>);
other=(tpos&);
ta=(str[num]&(<<(-other)) );
if(ta==)
{
build_tree(tpos+,g[head].l);
}
else build_tree(tpos+,g[head].r);
}
} int check_tree(int s)
{
if(g[s].flag==)
{
int tn=g[s].end_point;
if(len!=word_len[tn]) return ;
for(int i=;i<len;i++)
{
if(str[i]!=saveword[ word_pos[tn]+i ]) return ;
}
return ;
}
int tpos=g[s].pos;
int num=(tpos>>);
int other=(tpos&);
int ta;
ta=(str[num]&(<<(-other)) );
if(ta!=) return check_tree(g[s].r);
else return check_tree(g[s].l);
} void check()
{
//freopen("G:\\session1\\checklist.dat","r",stdin);
//cin>>T;
//getchar(); //int ansans=0;
for(int i=;i<;i++)
{
strcpy(str,qest[i]);
len=strlen(str);
str[len]='#';
len++;
str[len]=;
for(int j=;j<len;j++)
{
if(str[j]>='A'&&str[j]<='Z')
str[j]=str[j]-'A'+'a';
}
int sign1=check_tree();
//ansans+=sign1;
if(sign1==)
flag_ans[i]=;
//if(sign1==1) printf("%s\n",str);
//T--;
//if(T==0) break;
}
} int main()
{
freopen("checklist.dat","r",stdin);
freopen("checkedresult.dat","w",stdout);
int tcnt=;
while(scanf("%s",qest[tcnt])!=EOF) tcnt++;
//printf("%d\n",tcnt);
freopen("emaillist.dat","r",stdin);
//int T;
//cin>>T;
//getchar();
n=;
cnt=;
int first_flag=;
int tmp_pos=;
int cntt=;
while(scanf("%s",str)!=EOF)
{
cntt++;
if(cntt==)
{
char tstr[];
strcpy(tstr,str);
check();
cnt=;
n=;
first_flag=;
tmp_pos=;
strcpy(str,tstr);
}
word_pos[n]=tmp_pos;
len=strlen(str);
str[len]='#';
len++;
word_len[n]=len;
for(int i=;i<len;i++)
{
if(str[i]>='A'&&str[i]<='Z')
str[i]=str[i]-'A'+'a';
saveword[tmp_pos++] = str[i];
}
//然后就是构树了
if(first_flag==)
{
first_flag=;
g[].flag=;//为n号叶子结点。
g[].end_point=n;
cnt++;
}
else
{
build_tree(,);
}
n++;
//if(n%100000==0) printf("%d\n",n); //T--;
//if(T==0) break;
}
check();
int ansans=;
for(int i=;i<;i++)
{
if(flag_ans[i]==)
printf("yes\n");
else printf("no\n");
ansans+=flag_ans[i];
}
printf("%d\n",ansans);
return ;
}

PAT trie的更多相关文章

  1. Leetcode: Implement Trie (Prefix Tree) && Summary: Trie

    Implement a trie with insert, search, and startsWith methods. Note: You may assume that all inputs a ...

  2. uva 1401 dp+Trie

    http://uva.onlinejudge.org/index.php? option=com_onlinejudge&Itemid=8&page=show_problem& ...

  3. CF #Manthan, Codefest 16 C. Spy Syndrome 2 Trie

    题目链接:http://codeforces.com/problemset/problem/633/C 大意就是给个字典和一个字符串,求一个用字典中的单词恰好构成字符串的匹配. 比赛的时候是用AC自动 ...

  4. 可持久化 trie 的简单入门

    可持久化 $trie$  ....又是一个表里不一的东西..... 可持久化 $trie$  的介绍: 和主席树类似的,其实可持久化就是体现在前缀信息的维护上(搞不懂这怎么就叫做可持久化了...) $ ...

  5. poj_3987 Trie图

    题目大意 有N个病毒,病毒由A-Z字母构成,N个病毒各不相同.给出一段程序P,由A-Z字母构成,若病毒在在程序P或者P的逆转字符串P'中存在,则该程序P被该病毒感染.求出程序P被多少种病毒感染. 题目 ...

  6. 后缀树(Suffix Trie)子串匹配结构

    Suffix Trie 又称后缀Trie或后缀树.它与Trie树的最大不同在于,后缀Trie的字符串集合是由指定字符串的后缀子串构成的.比如.完整字符串"minimize"的后缀子 ...

  7. 标准Trie、压缩Trie、后缀Trie

    ref : https://dsqiu.iteye.com/blog/1705697 1.Trie导引 Trie树是一种基于树的数据结构,又称单词查找树.前缀树,是一种哈希树的变种.应用于字符串的统计 ...

  8. luoguP6623 [省选联考 2020 A 卷] 树(trie树)

    luoguP6623 [省选联考 2020 A 卷] 树(trie树) Luogu 题外话: ...想不出来啥好说的了. 我认识的人基本都切这道题了. 就我只会10分暴力. 我是傻逼. 题解时间 先不 ...

  9. 《转载》PAT 习题

    博客出处:http://blog.csdn.net/zhoufenqin/article/details/50497791 题目出处:https://www.patest.cn/contests/pa ...

随机推荐

  1. 持续集成之代码质量管理-Sonar

    原文:http://blog.csdn.net/abcdocker/article/details/53840582 Sonar介绍 Sonar 是一个用于代码质量管理的开放平台.通过插件机制,Son ...

  2. Scapy基础学习之中的一个

    关于Scapy Scapy的是一个强大的交互式数据包处理程序(使用python编写). 它可以伪造或者解码大量的网络协议数据包,可以发送.捕捉.匹配请求和回复包等等.它可以非常easy地处理一些典型操 ...

  3. CSS之Position全面认识

    CSS的很多其他属性大多容易理解,比如字体,文本,背景等.有些CSS书籍也会对这些简单的属性进行大张旗鼓的介绍,而偏偏忽略了对一些难缠的属 性讲解,有避重就轻的嫌疑.CSS中主要难以理解的属性包括盒型 ...

  4. 将DataSet转换成json

     /// <summary>        /// 把dataset数据转换成json的格式        /// </summary>        /// <para ...

  5. C/C++中,空数组、空类、类中空数组的解析及其作用

    转自:http://blog.sina.com.cn/s/blog_93b45b0f01015s95.html 我们经常会遇到这些问题: (1)C++中定义一个空类,他们它的大小(sizeof) 为多 ...

  6. Shift Register(Using Submodule)

    /*************************************************** /  Shift Register module by Submodule /  Progra ...

  7. Google Pagespeed,自动压缩优化JS/CSS/Image

    Google Pagespeed,自动压缩优化JS/CSS/Image 浏览: 发布日期:// 分类:技术分享 关键字: Nginx Appache Pagespeed 自动压缩优化JS/CSS/Im ...

  8. 5 月 35 日临近,Google 无法访问,可以使用 Google IP 来解决。

    每年都会有几天那啥,你懂的. 直接使用 Google 的域名访问经常会打不开,而使用 Google 的 IP 就会很顺畅. 使用 Chrome 浏览器我们经常都会在地址栏直接搜索,所以我们只要添加一个 ...

  9. php做推送服务端实现ios消息推送

    本文部分内容引用于 http://zxs19861202.iteye.com/blog/1532460 准备工作 1.获取手机注册应用的deviceToken(iphone手机注册应用时返回唯一值de ...

  10. constructors and destructors

    A constructor is a method that gets called immediately when an object is allocated (on the stack or ...