1、(完整版)算法合集之浅析“最小表示法”思想在字符串循环同构问题中的应用浅析“最小表示法”思想在字符串循环同构问题中的应用安徽省芜湖市第一中学周源 【目录】浅析“最小表示法思想在字符串循环同构问题中的应用1【目录】1【摘要】2【关键字】2【正文】3一、问题引入31.明确几个记号和概念32.问题3二、枚举算法和匹配算法31.枚举算法32。匹配算法33.小结4三、最小表示法思想41.“最小表示法”思想的提出42。“最小表示法”思想的定义43。“最小表示法”在本题的应用54.模拟算法执行75。小结8四、总结8【摘要】最小表示法在搜索判重、判断图的同构等很多问题中有着重要的应用。本文就围绕字符串循环同构
2、的判断这个问题,在很容易找到O(N)的匹配后,本文引进的“最小表示法”思想,并系统的对其下了定义,最后利用“最小表示法”思想构造出了更优秀,更自然的算法。无论是增加“最小表示法”思想这方面的知识,提高增加竞赛中的综合素质,相信本文对同学们还是有所裨益的.【关键字】字符串 循环同构 匹配 最小表示法【正文】一、 问题引入1. 明确几个记号和概念由于本篇论文主要讨论与字符串有关的算法,所以在本文中,一切未经说明的以开头的变量均表示字符串。,即的长度。为的第个字符.这里。,即截取出的第个字符到第个字符的子串。这里。特别的,。定义的一次循环;而的次循环,的零次循环。如果字符串可以经过有限次循环得到,即
3、有,则称和是循环同构的。设有两个映射,定义和的连接,这里。-这个定义用于后文算法描述中。2. 问题给定两个字符串和,判断他们是否循环同构.二、 枚举算法和匹配算法1. 枚举算法很容易知道,的不同的循环串最多只有个,即,所以只需要把他们一一枚举,然后分别与比较即可.枚举算法思维简单,易于实现,而它的时间复杂度是级这里N=|s1|=|s2|。,已经可以胜任大多数问题的要求了.然而如果大至几十万,几百万,枚举算法就无能为力了,有没有更优秀的算法呢?2. 匹配算法从枚举算法执行过程中很容易发现,枚举算法的本质就是在一个可以循环的字符串中寻找的匹配,于是联想到模式匹配的改进算法是级的,那么在循环串中寻找
4、匹配是不是也有线性的算法呢?回答是肯定的:由于循环串与一般的字符串本质的区别就是前者是“循环”的,如果能去掉“循环”这个限制,那么就可以直接套用一般字符串的模式匹配算法了!显然,将复制两次:做为主串,则任何与循环同构的字符串至少都可以在中出现一次,于是可以说就是循环串的一般字符串形式!问题成功转化为求在中的模式匹配。这完全可以在级时间内解决.3. 小结很容易得到的枚举算法显然不能满足大数据的要求,于是我们从算法的执行过程入手,探查到了枚举算法的实质:模式匹配.最后,通过巧妙的构造、转换模型,直接套用模式匹配算法,得到了级别的算法。但是问题是否已经完美解决了呢?也许你会说:以KMP算法为首的模式
5、匹配改进算法,都是以难理解,难记忆著称的!这的确是KMP算法的缺点,而且其next数组繁琐的计算严重制约着算法的可扩展性,看来是有必要寻求更简洁的算法了。三、 最小表示法思想1. “最小表示法思想的提出首先来看一个引例:引例有两列数,和,不记顺序,判断它们是否相同.分析由于题目要求“不记顺序”,因此每一列数的不同形式高达种之多!如果要一一枚举,显然是不科学的。于是一种新的思想提出了:如果两列数是相同的,那么将它们排序之后得到的数列一定也是相同的。于是,算法复杂度迅速降为级。这道题虽然简单,却给了我们一个重要的启示:当某两个对象有多种表达形式,且需要判断它们在某种变化规则下是否能够达到一个相同的
6、形式时,可以将它们都按一定规则变化成其所有表达形式中的最小者,然后只需要比较两个“最小者是否相等即可!下面我们系统的给出“最小表示法”思想的定义。2. “最小表示法”思想的定义设有事物集合和映射集合,其中是到的映射:。如果两个事物,有一系列映射的连接使,则说和是本质相同的。这里满足:任意,一定能在中一系列映射的连接的作用下,仍被映射至。任意,若有使,则一定存在一个或一系列映射,他们的连接。由的性质可知,和是本质相同的,即“本质相同这个概念具有自反性。从性质可知,如果和是本质相同的,那么和也一定是本质相同的。即“本质相同”这个概念具有对称性。另外,根据“本质相同概念的定义很容易知道,“本质相同”
7、这个概念具有传递性。即若和是本质相同,和是本质相同,那么一定有和是本质相同的。给定和,如何判断中的两个事物和是否互为本质相同的呢?“最小表示法”就是可以应用于此类题目的一种思想。它规定中的所有事物均有一种特殊的大小关系。然后,根据中的变化规则,将和均化为规定大小关系中的最小者和,如果两者相同,则易知,和本质相同,和本质相同,和本质相同,所以和是本质相同的.否则,可以证明,和不是本质相同的。3. “最小表示法在本题的应用在本题中,事物集合表示的是不同的字符串,而映射集合则表示字符串的循环法则,“事物中的大小关系”就是字符串间的大小关系。那么,如何将最小表示法应用于本题呢?最简单的方法就是根据上文
8、,分别求出和的最小表示,比较它们是否相同。如果要是很简单的这么做,问题就非常麻烦了:求字符串的最小表示法虽然有级算法,但是思路十分复杂,还不如匹配算法-如果单纯得这么做,就违背了我们寻找更好算法的初衷。这样,看上去“最小表示法”是无能为力了.然而我们换一种思路:和匹配算法相似,将和各复制一次:,;并设两个指针和分别指向和的第一个字符。设,也就是说函数返回的是最小表示串的第一个字符在原串中的位置注意,这里所说的“在原串中的位置”,并不是单纯的在原串中寻找到的第一个匹配,而是以之开头的循环串是原串的最小表示。,如果有多个最小表示串,则取在原串中位置最小的一个。显然如果和是循环同构的,且当前两指针且
9、的时候,一定可以得到,迅速得到和是循环同构的。当且时,两指针仍然有机会达到,这个状态。于是问题转化成:仍然设和是循环同构的,当前两指针分别向后滑动比较,如果发现比较失败,有,如何向后滑动指针,使新指针仍然满足和仍然满足。u串:ixi+ki(i+k+1)|s1|w串:jj+(x-i)j+kj+k+1|s2|相等大于从不相等的和下手:如果,那么任意整数,从第个字符开头的循环串是,如图,的前个字符是,当然,也可以表示为,对称的,可以在串中找到一段字符,这两段字符串长度相等,而且根据上文假设的扫描过程可以得到。而,所以得到,即.而根据假设和是循环同构的,那么一定能在的所有循环串中找到一个字符串,满足它
10、的前个字符是.于是有,得一定不是的最小表示。所以不可能在一段中,也就可以将指针向后滑动个字符:。同理得到如果,可将指针向后滑动个字符:.仍满足,。于是设计出算法:将和各复制一次:,;并设两个指针和分别指向和的第一个字符.如果和均中至少一个大于,则可以肯定和不是循环同构的,返回,算法结束;否则找到最小的使,如果这样的不存在或,则说明,即和各有一段长为的子串相等,和是循环同构的,返回,算法结束;否则转第步。如果,则将指针向后滑动个字符:;否则说明,就将指针向后滑动个字符:。继续执行第步。容易得出,本算法的时空复杂度也是均为级。更清楚一点,我们附上一个例子:4. 模拟算法执行设,,显然它们是循环同构
11、的。模拟执行算法是这样的:首先有,并设指针。第一次执行、两步:第一次执行完毕后得到,下面第二次执行:现在结果是,同理执行第三次:此时已经是,执行第四次:这时发现!成功得出和是循环同构的,算法返回值为真.5. 小结经过一番努力,我们终于得到了一个与匹配算法本质不同的线性算法.在这个问题中,“最小表示法”思想引导我们从问题的另一方面分析,进而构造出一个全新的算法。比起匹配算法,它容易理解,便于记忆,实现起来,也不过是短短的几重循环,非常方便,便于应用于扩展问题。四、 总结“最小表示法”是判断两种事物本质是否相同的一种常见思想,它的通用性也是被人们认可的-无论是搜索中判重技术,还是判断图的同构之类复杂的问题,它都有着无可替代的作用。深入分析不难得出,该思想的精华在于引入了“序”这个概念,将待比较两个事物化为规定顺序中最小的(也可能是最大的)再加以比较.然而值得注意的是,在如今的信息学竞赛中,试题纷繁复杂,使用的算法也不再拘泥于几个经典的算法,改造经典算法或是将多种算法组合是常用的方法之一。正如本文讨论的问题,单纯的寻求字符串的最小表示显得得不偿失,但利用“最小表示法”的思想,和字符串的最小表示这个客观存在的事物,我们却找到了一个简单、优秀的算法。因此,在解决实际问题时,只有深入分析,敢于创新,才能将问题化纷繁为简洁,化无序为有序。