字符串的有关算法教程.ppt

  1. 1、本文档共96页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
字符串的有关算法教程

字符串的相关算法;还是在前面的话;大前天提到了分治… 提到了这样一个方程… f(n)=f(n/2)+f(n/2)+O(1) 这个咱当时是说f(n)=O(nlogn) 那是咱SB… Too Na?ve 考虑线段树的节点,就是这个分布的… 可是线段树的节点个数是O(n)的 这个的解显然应该是f(n)=O(n) 在此表示歉意;咱所知道的字符串算法 Pascal的Pos函数… Hash哈希 Kmp和扩展Kmp Trie树 AC自动机 后缀树,后缀数组(SA),后缀自动机(SAM) Manacher算法 乱搞 最近新出来的:回文自动机(PAM)(太弱不会)。 ;Hash哈希;实际上这种计算方法,每个字符串都是X进制下的一个数,而Hash值就是这个X进制的数转十进制的值,由于X进制的数互不相同,显然Hash值,即十进制的数也互不相同。 Q:那如果字符串长度过大,以致会爆怎么办? 取个模呗… Q:那如果两个字符串不同Hash值取某个模最后相同怎么办? 取多个模呗…如果多个模的情况下都相同那么就是同一个字符串。 Q:如果取多个模都相同呢? …… 首先,这个模是你自己定的,所以一般数据是没办法全部卡的。接着,由中国剩余定理,只要取到的每个模足够大,那么最后也可以保证一定范围内的Hash值是一定的。 Q:中国剩余定理是什么? 以后讲数学的时候会讲吧…顺便可以百度_(:зゝ∠)_;除了这种Hash以外,字符串Hash也有很多其他的版本,比如ELFhash(黑书上的) 据说这个的效果比上面的还好,咱没试过_(:зゝ∠)_ Function ELFhash(var s:string):integer; Var g,h,i:longint; Begin h:=0; for i:=1 to length(s) do begin h:=h shl 4+Ord(S[i]); g:=h and $f0000000 ($是十六进制) if g0 then h:=h xor (g shr 24); h:=h and (not g); end; ELFhash:=h mod M; End;;Bzoj1014 JSOI2008 火星人;题目是什么意思?一般先化成裸题。 LCP是最长公共前缀,现给出一个字符串S,支持以下操作: 1 询问 LCP(x,y),也就是原字符串从x开始的字符串和从y开始的字符串最长的公共前缀 2 修改,修改原S的一个字符 3 添加,在S的第X个字符后面添加一个字符。 这个有什么做法? ;也是可以把问题分开来考虑,比如,怎么快速求LCP? Hash? 考虑使用Hash来做 实际上这里的LCP(x,y)的x,y所代表的字符串都是S的后缀 考虑??一个后缀Suffix[i],就是从S的第i个字符开始的后缀,它的Hash值就是Hash[i]=S[i]+S[i+1]*26+S[i+2]*26^2... 然后Suffix[i]的某个前缀S[i..j]的Hash值怎么算? Hash=Hash[i]-Hash[j]*26^(j-i+1) 预处理出所有后缀的Hash[i]以及26^k的话 也就是说咱们能够O(1)地求出每一个后缀的某个前缀的Hash值。 ;之前又提到过一点: 对于两个相同的字符串,他们的Hash值相同,取模之后也相同。 对于两个不同的字符串,他们的Hash值不相同,但取模之后可能相同,模的数越大,同时取不同的模,最后相同的可能性越小。 以这两点作为依据,咱们可以这样子做。 对于询问后缀X与Y的询问,二分答案,即LCP的长度L,然后O(1)求出这个长度为L的前缀的Hash值,取不同的模,如果不同的模之后都相同,则可认为这两个长度为L的字符串相同,二分答案区间上移,否则则认为不同,二分答案区间下移。 这样做的复杂度是O(logS)一次,S为字符串的长度。;但是对于修改操作,咱们该怎么做? 咱们可以发现,修改了字符S[i],那么受到影响的就是它前面的所有字符的Hash值,对于前面来说这个改动比较大… 而添加字符…对于所有的Hash值,都要重算… 这怎么做啊,这没法做啊… 实际上还是可以做的…咱们以原字符串的顺序建立平衡树,每个节点i维护一个信息,就是它为根的子树所构成的字符串的Hash值和它为根的子树的大小size。;那么递推式?Hash[fa]=Hash[lson]+s[fa]*26^(Size[lson])+Hash[rson]*26^(Size[lson]+1) 然后这样子就可以做了…每一次把一个后缀全部弄到一棵子树里面,然后它的Hash值就是根节点的那个Hash值。 这个得用Splay来做 对于修改,直接在子

文档评论(0)

dajuhyy + 关注
实名认证
内容提供者

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

1亿VIP精品文档

相关文档