字符串处理 —— 最大最小表示法

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011815404/article/details/87985191

【概述】

最大最小表示法用于解决字符串的同构问题,其在复杂度为 O(n) 的时间内求出一个字符串的所有同构串中字典序最大(小)的串的起始位置。

应用:

  • 给出 n 个循环字符串判断有多少不同字符串:逐个用最大(小)表示法表示,然后加入 set 去重
  • 循环字符串所有同构串中字典序最大(小)的表示:用最大(小)表示法求出起始位置,输出即可
  • 判断两个字符串是否同构:将两字符串用最大(小)表示法表示,然后逐个字符比较

【算法原理】

设一字符串 S,且 S’ 是 S 的循环同构的串的最小表示,那么对于字符串循环同构的最小表示法,其问题实质是求 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 即可

可以看出,朴素算法在 S[i]=S[j] 时,i 的指针移动的太少了,在遇到像 bbb…bbbbbba 这样复杂的字符串时,时间复杂度可能会退化到 O(n^2),针对这一问题加以改进可得到 O(n) 的最小表示法的算法,其核心思路是在 S[i]=S[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=i+k
    否则 j++

最后返回 i 和 j 的小者即可

【实现】

1.最小表示法

int minmumRepresentation(char *str){//最小表示法
    int len=strlen(str);
    int i=0;//指向字符串最小的位置
    int j=1;//比较指针
    int k=0;//str[i]与str[j]相等时一次移动几个
    while(i<len&&j<len&&k<len){
        int temp=str[(i+k)%len]-str[(j+k)%len];//比较值的长度
        if(temp==0)
            k++;
        else{
            if(temp>0)//维护i
                i=i+k+1;
            else//维护j
                j=j+k+1;
            if(i==j)//相等时比较指针后移
                j++;
            k=0;
        }
    }
    return i<j?i:j;//返回i、j中较小的那个
}

2.最大表示法

int maxmumRepresentation(char *str){//最大表示法
    int len=strlen(str);
    int i=0;//指向字符串最小的位置
    int j=1;//比较指针
    int k=0;//str[i]与str[j]相等时一次移动几个
    while(i<len&&j<len&&k<len){
        int temp=str[(i+k)%len]-str[(j+k)%len];//比较值的长度
        if(temp==0)
            k++;
        else{
            if(temp>0)//维护i
                j=j+k+1;
            else//维护j
                i=i+k+1;
            if(i==j)//相等时比较指针后移
                j++;
            k=0;
        }
    }
    return i<j?i:j;//返回两者最小值
}

【例题】

  1. How many(HDU-2609)(最小表示法求不同构串个数)点击这里
  2. String Problem(HDU-3374)(最小最大表示法+kmp)点击这里

猜你喜欢

转载自blog.csdn.net/u011815404/article/details/87985191
今日推荐