网站大量收购独家精品文档,联系QQ:2885784924

字典树模板acm竞赛可用.docVIP

  1. 1、本文档共4页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  5. 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  6. 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  7. 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  8. 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
字典书模板   今天AC了两题trie tree的题目,感觉trie的性质真的是相当的好,而且实现比较简单。它使在字符串集合中查找某个字符串的操作的复杂度降到最大只需O(n),其中n为字符串的长度。trie是典型的将时间置换为空间的算法,好在ACM中一般对空间的要求很宽松。 ? ? trie的原理是利用字符串集合中字符串的公共前缀来降低时间开销以达到提高效率的目的。 它具有以下性质:1,根结点不包含任何字符信息;2,如果字符的种数为n,则每个结点的出度为n(这样必然会导致浪费很多空间,这也是trie的缺点,我还没有想到好点的办法避免);3,查找,插入复杂度为O(n),n为字符串长度。 ? ? 举一个例子,给50000个由小写字母构成的长度不超过10的单词,然后问某个公共前缀是否出现过。如果我们直接从字符串集中从头往后搜,看给定的字符串是否为字符串集中某个字符串的前缀,那样复杂度为O(50000^2),这样显然会TLE。又或是我们对于字符串集中的每个字符串,我们用MAP存下它所有的前缀。然后询问时可以直接给出结果。这样复杂度为O(50000*len),最坏情况下len为字符串最长字符串的长度。而且这没有算建立MAP存储的时间,也没有算用MAP查询的时间,实际效率会更低。但如果我们用trie的话,当查询如字符串abcd是否为某字符串的前缀时,显然以b,c,d....等不是以a开头的字符串就不用查找了。实际查询复杂度只有O(len),建立trie的复杂度为O(50000).这是完全可以接受的。 ? ? 如给定字符串集合abcd,abd,cdd,efg,hij,hi六个字符串建立的trie tree如下图所示: 查找一个字符串时,我们只需从根结点按字符串中字符出现顺序依次往下走。如果到最后字符串结束时,对应的结点标记为红色,则该字符串存在;否则不存在。 ? ? 插入时也只需从根结点往下遍历,碰到已存在的字符结点就往下遍历,否则,建立新结点;最后标记最后一个字符的结点为红色即可。 ? ? 同时我们看到,如果字符的种类为n,则需要结点的个数为n级数。(谁有好办法降低空间开销,请告诉我) 题目: /showproblem.php?pid=1251 题目和我上面举的例子差不多,是说给定一个字符串集合,然后每次询问时给出一个字符串,问以该字符串为前缀的字符串在集合中有多少个。先给个用MAP版本的,限时2000MS的题目,用MAP,1750MS,险过。 my code1: #includeiostream #includemap #includestring using namespace std; int main() { ? ? int i,j,k,len; ? ? string str;char temp[15],temp1[15]; ? ? map string,int mymap; ? ? while(gets(temp)) ? ? { ? ? ? ? if(temp[0]==\n) break; ? ? ? ? len=strlen(temp); ? ? ? ? if(len==0) break; ? ? ? ? for(i=0;ilen;i++)//求出某个字符串的所有前缀,并用MAP存起来 ? ? ? ? { ? ? ? ? ? ? for(j=0;j=i;j++) temp1[j]=temp[j];temp1[j]=\0; ? ? ? ? ? ? str.assign(temp1); ? ? ? ? ? ? mymap[str]++; ? ? ? ? } ? ? } ? ? while(scanf(%s,temp)!=EOF) ? ? ? ? coutmymap[temp]endl;//此时直接输出结果即可 ? ? return 0; } 用MAP的特点是代码短,思路简单,很容易实现,但耗时大。下面给出trie版本的。 my code2: #includeiostream using namespace std; const int kind=26;//字母种类 struct Treenode//树的结点结构 { ? ? int count;//这个附加变量在本题中记录遍历到该结点形成的字符串出现的次数,在不同题中可记录不同的内容。 ? ? Treenode *next[kind];//指向儿子结点 ? ? Treenode()//每个结点的初始化 ? ? { ? ? ? ? count=1; ? ? ? ? for(int i=0;ikind;i++) ? ? ? ? ? ? next[i]=NULL; ? ? } }; void insert(Treenode *root,char *word)//向以r

文档评论(0)

JuanHuang + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档