zoukankan      html  css  js  c++  java
  • 理解字符串循环同构的最小表示法


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

    对于一个字符串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的性质,而不是看论文时给人感觉的处理两个字符串。
    应用最小表示法判断两个字符串同构,只要将两个串的最小表示求出来,然后从最小表示开始比较。剩下的工作就不用多说了。

    [cpp:nogutter] view plaincopy
    1. int MinimumRepresentation(char *s, int l)  
    2. {  
    3.     int i = 0, j = 1, k = 0, t;  
    4.     while(i < l && j < l && k < l) {  
    5.         t = s[(i + k) >= l ? i + k - l : i + k] - s[(j + k) >= l ? j + k - l : j + k];  
    6.         if(!t) k++;  
    7.         else{  
    8.             if(t > 0) i = i + k + 1;  
    9.             else j = j + k + 1;  
    10.             if(i == j) ++ j;  
    11.             k = 0;  
    12.         }  
    13.     }  
    14.     return (i < j ? i : j);  
    15. }  
  • 相关阅读:
    c#类的小小理解
    sql语句:保留要害字的问题.例如 size,text,user等
    c#2005做新闻发布系统心得
    asp 遇到过的问题集锦,附加asp语句添加数据库和生成表,asp命令更改指定文件的文件名,asp值传递的应用091116小结
    dropdownlist控件失去焦点的小应用和函数substr
    获得当前应用程序路径C#03
    模糊查询简单分析,得出sql语句
    20080905经典的DataReader对象解读+几种对数据库的操作的命令,20100111update read db example
    Servlet 容器的工作原理 ( 二 )
    手低眼高 初学者学习Hibernate的方法
  • 原文地址:https://www.cnblogs.com/catkins/p/5270774.html
Copyright © 2011-2022 走看看