博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
字符串最小表示法模板
阅读量:5248 次
发布时间:2019-06-14

本文共 1271 字,大约阅读时间需要 4 分钟。

循环字符串的最小表示法的问题可以这样描述:

 

对于一个字符串S,求S的循环的同构字符串S’中字典序最小的一个。由于语言能力有限,还是用实际例子来解释比较容易:

 设S=bcad,且S’是S的循环同构的串。S’可以是bcad或者cadb,adbc,dbca。而且最小表示的S’是adbc。 对于字符串循环同构的最小表示法,其问题实质是求

S串的一个位置,从这个位置开始循环输出S,得到的S’字典序最小。 一种朴素的方法是设计i,j两个指针。其中i指向最小表示的位置,j作为比较指针。 令i=0,j=1 

如果S[i] > S[j] i=j, j=i+1 

如果S[i] < S[j] j++

如果S[i]==S[j] 设指针k,分别从i和j位置向下比较,直到S[i] != S[j]    

  如果S[i+k] > S[j+k] i=j,j=i+1 

  否则 j++ 

返回i 

起初,我想在j指针后移的过程中加入一个优化。就是j每次不是加1,而是移动到l位置。其中,l>j且S[l]<=S[j]。但是,即使加入这一优化,在遇到bbb…bbbbbba这样的字符串时

复杂度将退化到O(n^2)。

注意到,朴素算法的缺陷在于斜体的情况下i指针的移动太少了。针对这一问题改进就得到了最小表示法的算法。最小表示法的算法思路是维护两个指针i,j。

 令i=0,j=1 

如果S[i] > S[j] i=j, j=i+1 

如果S[i] < S[j] j++ 

如果S[i]==S[j] 

  设指针k,分别从i和j位置向下比较,直到S[i] != S[j] 

  如果S[i+k] > S[j+k] i=i+k 

  否则j++ 

返回i和j的小者

 

注意到上面两个算法唯一的区别是粗体的一行。这一行就把复杂度降到O(n)了。

 

值得一提的是,与KMP类似,最小表示法处理的是一个字符串S的性质,而不是看论文时给人感觉的处理两个字符串。 

应用最小表示法判断两个字符串同构,只要将两个串的最小表示求出来,然后从最小表示开始比较。剩下的工作就不用多说了。  

int get_min()   {        int i=0,j=1,k=0,t,l=strlen(s);    while(i
0) j=j+k+1; else i=i+k+1; if(i==j) j++; k=0; } } return (i

 

转载于:https://www.cnblogs.com/sweat123/p/4723265.html

你可能感兴趣的文章
ABAP 创建和调用WebService
查看>>
C# 实例化顺序
查看>>
CSS水平垂直居中总结
查看>>
委托又给我惹麻烦了————记委托链的取消注册、获取返回值
查看>>
ps怎么把白色背景变透明
查看>>
gource 安装教程
查看>>
字符串转 Boolean 的正确方式
查看>>
给你的网站404页面加上“宝贝寻亲”公益页面
查看>>
整理推荐的CSS属性书写顺序
查看>>
协程, IO阻塞模型 和 IO非阻塞模型
查看>>
Spring工作原理及其作用
查看>>
内容营销11金规
查看>>
ServerSocket和Socket通信
查看>>
Java中的Comparable<T>和Comparator<T>接口
查看>>
数据结构——链式线性表
查看>>
css & input type & search icon
查看>>
jQuery插件开发详细教程
查看>>
Crontab 在linux中的非常有用的Schedule Jobs
查看>>
ProxySQL Scheduler
查看>>
mdb2csv
查看>>