数据结构字符串.pptx
《数据结构字符串.pptx》由会员分享,可在线阅读,更多相关《数据结构字符串.pptx(86页珍藏版)》请在三一办公上搜索。
1、字符串,字符串,字符串的范畴非常广泛;难题往往在此节出现;掌握字符串的法门是。字符串问题的晦涩代表:KMP、Manacher,主要内容,需要掌握的内容字符串循环左移LCS最长递增子序列字符串全排列递归、非递归KMPHuffman编码需要了解的内容Manacher算法BM算法,字符串循环左移,4/88,给定一个字符串S0N-1,要求把S的前k 个字符移动到S的尾部,如把字符串“abcdef”前面的2个字符a、b移动到字符串的尾 部,得到新字符串“cdefab”:即字符串循环 左移k。多说一句:循环左移k位等价于循环右移n-k位。算法要求:时间复杂度为 O(n),空间复杂度为 O(1)。,问题分析
2、,5/88,暴力移位法每次循环左移1位,调用k次即可时间复杂度O(kN),空间复杂度O(1)三次拷贝S0k T0kSk+1N-1 S0N-k-1T0k SN-kN-1时间复杂度O(N),空间复杂度O(k),优雅一点的算法,6/88,(XY)=YX如:abcdefX=abX=baY=cdefY=fedc(XY)=(bafedc)=cdefab时间复杂度O(N),空间复杂度O(1)该问题可以作为“完美洗牌”算法的子算法。,Code,7/88,LCS的定义,8/88,最长公共子序列,即Longest Common Subsequence,LCS。一个序列S任意删除若干个字符得到新序列T,则T 叫做S
3、的子序列;两个序列X和Y的公共子序列中,长度最长的那 个,定义为X和Y的最长公共子序列。字符串13455与245576的最长公共子序列为455字符串acdfg与adfc的最长公共子序列为adf注意区别最长公共子串(Longest Common Substring)最长公共字串要求连续,LCS的意义,9/88,求两个序列中最长的公共子序列算法,广泛的应用 在图形相似处理、媒体流的相似比较、计算生物学 方面。生物学家常常利用该算法进行基因序列比 对,由此推测序列的结构、功能和演化过程。LCS可以描述两段文字之间的“相似度”,即它们的 雷同程度,从而能够用来辨别抄袭。另一方面,对 一段文字进行修改之
4、后,计算改动前后文字的最长 公共子序列,将除此子序列外的部分提取出来,这 种方法判断修改的部分,往往十分准确。简而言 之,百度知道、百度百科都用得上。,暴力求解:穷举法,10/88,假定字符串X,Y的长度分别为m,n;X的一个子序列即下标序列1,2,m的严格递增 子序列,因此,X共有2m个不同子序列;同理,Y 有2n个不同子序列,从而穷举搜索法需要指数时间 O(2m.2n);对X的每一个子序列,检查它是否也是Y的子序 列,从而确定它是否为X和Y的公共子序列,并且 在检查过程中选出最长的公共子序列;显然,不可取。,LCS的记号,11/88,字符串X,长度为m,从1开始数;字符串Y,长度为n,从1
5、开始数;Xi=x1,xi即X序列的前i个字符(1im)(Xi不妨读作“字符串X的i前缀”)Yj=y1,yj即Y序列的前j个字符(1jn)(字符串Y的j前缀);LCS(X,Y)为字符串X和Y的最长公共子序列,即 为Z=z1,zk。注:不严格的表述。事实上,X和Y的可能存在多个子 串,长度相同并且最大,因此,LCS(X,Y)严格的说,是 个字符串集合。即:Z LCS(X,Y).,LCS解法的探索:xm=yn,12/88,若xm=yn(最后一个字符相同),则:Xm与Yn 的最长公共子序列Zk的最后一个字符必定为 xm(=yn)。zk=xm=ynLCS(Xm,Yn)=LCS(Xm-1,Yn-1)+xm
6、,结尾字符相等,则LCS(Xm,Yn)=LCS(Xm-1,Yn-1)+xm,记LCS(Xm,Yn)=W+xm,则W是Xm-1的子序列;同 理,W是Yn-1的子序列;因此,W是Xm-1和Yn-1的公 共子序列。反证:若W不是Xm-1和Yn-1的最长公共子序列,不妨记 LCS(Xm-1,Yn-1)=W,且|W|W|;那么,将W换成W,得到更长的LCS(Xm,Yn)=Wxm,与题设矛盾。,13/88,举例:xm=yn,14/88,对于上面的字符串X和Y:x3=y3=C,则:LCS(BDC,ABC)=LCS(BD,AB)+Cx5=y4=B,则:LCS(BDCAB,ABCB)=LCS(BDCA,ABC)
7、+B,LCS的探索:xmyn,若xmyn,则:要么:LCS(Xm,Yn)=LCS(Xm-1,Yn)要么:LCS(Xm,Yn)=LCS(Xm,Yn-1)证明:令Zk=LCS(Xm,Yn);由于xmyn则zkxm与zkyn至少有 一个必然成立,不妨假定zkxm(zkyn的分析与之类似)因为zkxm,则最长公共子序列Zk是Xm-1和Yn得到的,即:Zk=LCS(Xm-1,Yn)同理,若zkyn,则Zk=LCS(Xm,Yn-1)即,若xmyn,则:LCS(Xm,Yn)=maxLCS(Xm-1,Yn),LCS(Xm,Yn-1),15/88,举例:xmyn,16/88,对于字符串X和Y:x2y2,则:LC
8、S(BD,AB)=max LCS(BD,A),LCS(B,AB)x4y5,则:LCS(BDCA,ABCBD)=max LCS(BDCA,ABCB),LCS(BDC,ABCBD),LCS分析总结,17/88,显然,属于动态规划问题。,mn,mn,当x y,当xm=yn,m1nmn1,maxLCS(X,Y),LCS(X,Y),LCS(Xm1,Yn1)+xm,LCS(X,Y)=,算法中的数据结构:长度数组,18/88,使用二维数组Cm,nci,j记录序列Xi和Yj的最长公共子序列的长 度。当i=0或j=0时,空序列是Xi和Yj的最长公共子序 列,故ci,j=0。,j,i,j,i,当i 0,j 0,且
9、x y,maxc(i 1,j),c(i,j 1),当i 0,j 0,且x=y,当i=0或者j=0,0,c(i,j)=c(i 1,j 1)+1,算法中的数据结构:方向变量,19/88,使用二维数据Bm,n,其中,bi,j标记ci,j 的值是由哪一个子问题的解达到的。即ci,j 是由ci-1,j-1+1或者ci-1,j或者ci,j-1的哪一 个得到的。取值范围为Left,Top,LeftTop 三种情况。,实例,X=Y=,20/88,Code,21/88,算法实现Demo,22/88,进一步思考的问题,23/88,方向数组b是完全可以省略的:数组元素ci,j的值仅由ci-1,j-1,ci-1,j和
10、ci,j-1 三个值之一确定,因此,在计算中,可以临时判 断ci,j的值是由ci-1,j-1,ci-1,j和ci,j-1中哪一 个数值元素所确定,代价是O(1)时间。若只计算LCS的长度,则空间复杂度为O(min(m,n)。在计算ci,j时,只用到数组c的第i行和第i-1行。因此,只要用2行的数组空间就可以计算出最长公 共子序列的长度。,最大公共子序列的多解性:求所有的LCS,当xmyn时:若LCS(Xm-1,Yn)=LCS(Xm,Yn-1),会导致多解:有多个最长公共子序 列,并且它们的长度相等。B的取值范围从1,2,3扩展到1,2,3,4深度/广度优先搜索,mn,mn,当x y,当xm=y
11、n,m1nmn1,maxLCS(X,Y),LCS(X,Y),LCS(Xm1,Yn1)+xm,LCS(X,Y)=,24/88,LCS的应用:最长递增子序列LIS,25/88,Longest Increasing Subsequence给定一个长度为N的数组,找出一个最长的 单调递增子序列。例如:给定数组 5,6,7,1,2,8,则其最长的单调递增子序列为5,6,7,8,长度为4。分析:其实此LIS问题可以转换成最长公子序列 问题,为什么呢?,使用LCS解LIS问题,26/88,原数组为A 5,6,7,1,2,8排序后:A1,2,5,6,7,8因为,原数组A的子序列顺序保持不变,而且排序 后A本身
12、就是递增的,这样,就保证了两序列的最 长公共子序列的递增特性。如此,若想求数组A的 最长递增子序列,其实就是求数组A与它的排序数 组A的最长公共子序列。此外,本题也可以直接使用动态规划/贪心法来求解,附:LIS的动态规划解法,长度为N的数组记为A=a0a1a2.an-1;记A的前i个字符构成的前缀串为Ai=a0a1a2.ai-1,以ai结尾的最长递增子序列记做 Li,其长度记为bi;假定已经计算得到了b0,1,i-1,如何计算bi呢?已知L0 L1 Li-1的前提下,如何求Li?,27/88,附:求解LIS,根据定义,Li必须以ai结尾;如果将ai分别缀到L0 L1 Li-1后面,是否允许呢?
13、如果aiaj,则可以将ai缀到Lj的后面,得到比Lj更长 的字符串。从而:bi=max(bj)+1,0ji且ajai计算bi:遍历在i之前的所有位置j,找出满足条件ajai的最大的bj+1;计算得到b0n-1后,遍历所有的bi,找出最大值 即为最大递增子序列的长度。时间复杂度为O(N2)。,28/88,附:Code,29/88,附:Code split,30/88,字符串的全排列,31/88,给定字符串S0N-1,设计算法,枚举S的 全排列。,递归算法,32/88,以字符串1234为例:1 234 2 134 3 214 4 231如何保证不遗漏保证递归前1234的顺序不变,递归Code,33
14、/88,如果字符有重复,34/88,去除重复字符的递归算法以字符1223为例:1 2232 1233 221带重复字符的全排列就是每个字符分别与它后面非 重复出现的字符交换。即:第i个字符与第j个字符交换时,要求i,j)中没有 与第j个字符相等的数。,Code,35/88,重复字符的全排列递归算法时间复杂度,36/88,f(n)=n*f(n-1)+n2f(n-1)=(n-1)*f(n-2)+(n-1)2f(n)=n*(n-1)*f(n-2)+(n-1)2)+n2 f(n-2)=(n-2)*f(n-3)+(n-2)2 f(n)=n*(n-1)*(n-2)*f(n-3)+(n-2)2)+n*(n-
15、1)2+n2=n*(n-1)*(n-2)*f(n-3)+n*(n-1)*(n-2)2+n*(n-1)2+n2=.n+1,空间换时间,37/88,空间换时间的方法,38/88,如果是单字符,可以使用mark256;如果是整数,可以遍历整数得到最大值max 和最小值min,使用markmax-min+1;如果是浮点数或其他结构,考虑使用Hash。事实上,如果发现整数间变化太大,也应该考 虑使用Hash;可以认为整数/字符的情况是最朴素的Hash。,全排列的非递归算法,39/88,起点:字典序最小的排列,例如12345终点:字典序最大的排列,例如54321过程:从当前排列生成字典序刚好比它大的 下一
16、个排列 如:21543的下一个排列是23145如何计算?,21543的下一个排列的思考过程,40/88,逐位考察哪个能增大一个数右面有比它大的数存在,它就能增大那么最后一个能增大的数是x=11应该增大到多少?增大到它右面比它大的最小的数y=3应该变为23xxx显然,xxx应由小到大排:145 得到23145,全排列的非递归算法:整理成算法语言,41/88,步骤:后找、小大、交换、翻转后找:字符串中最后一个升序的位置i,即:SkSk+1(ki),SiSi+1;查找(小大):Si+1N-1中比Ai大的最小值Sj;交换:Si,Sj;翻转:Si+1N-1思考:交换操作后,Si+1N-1一定是降序的以9
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 字符串

链接地址:https://www.31ppt.com/p-4540964.html